diff --git a/game/probe/board_shot_probe.gd b/game/probe/board_shot_probe.gd index 85fa5d23..76dcdade 100644 --- a/game/probe/board_shot_probe.gd +++ b/game/probe/board_shot_probe.gd @@ -26,7 +26,7 @@ var _cur_settlement = null # 当关 settlement(身份回调读取面—— func _ready() -> void: -# oracle: design/engineering/test-conventions.md:84(棋盘截图取证——渲染闸采集组) +# oracle: design/engineering/test-conventions.md:84 (棋盘截图取证——渲染闸采集组) # 运行前提=窗口化真渲染面(shot_probe 同款护栏——headless 下 frame_post_draw 永不触发+视口纹理恒空) if DisplayServer.get_name() == "headless": print("[board_shot] FAIL — 本探针必须窗口化运行(headless 无渲染面,截图必空);现行事实源=tools/render_gate.sh 取证段") @@ -182,7 +182,7 @@ func _ready() -> void: # 判据:环外径像素 ÷ 格边 落 0.82±1px;封印格最外圈 1px 框最暗值与相邻未封印未开格同位框最暗值差 ≤1/255 #(halo 在 0.455×格边归零——格边框不应被压暗;相邻未开格同砖纹理同套瓦片为无封印参照)。 func _seal_evidence(tag: String, view: Node, settlement: Object, off_img: Image, out: String) -> void: -# oracle: design/engineering/test-conventions.md:84(封印印记像素取证组) +# oracle: design/engineering/test-conventions.md:84 (封印印记像素取证组) var ms = settlement.minesweeper var seal_cell := Vector2i(-9, -9) var ref_cell := Vector2i(-9, -9) @@ -290,6 +290,7 @@ func _probe_identity_lookup(c: Vector2i): # 双帧逐像素比对:所有变化像素必须落在生效格的内缘带内 # (de < cell÷8——带外含砖心零侵入=禁整格染色/禁越圈);每个生效格须有实绘像素(不空转)。 func _check_dual_frames(tag: String, view, glow_cells: Dictionary, off_img: Image, on_img: Image) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var board = view.board() if board == null: _problems.append("%s 双帧比对取板失败(view.board() 为 null)" % tag) diff --git a/game/probe/fx_probe.gd b/game/probe/fx_probe.gd index dd1416e5..5ea3d1ad 100644 --- a/game/probe/fx_probe.gd +++ b/game/probe/fx_probe.gd @@ -8,7 +8,7 @@ extends Node func _ready() -> void: -# oracle: design/gdd/systems/战斗循环/战斗表现.md:148(结算演出——挖掘期零打扰组) +# oracle: design/gdd/systems/战斗循环/战斗表现.md:148 (结算演出——挖掘期零打扰组) await get_tree().process_frame var problems: Array = [] diff --git a/game/probe/fx_shot_probe.gd b/game/probe/fx_shot_probe.gd index d2f2375b..b7e15910 100644 --- a/game/probe/fx_shot_probe.gd +++ b/game/probe/fx_shot_probe.gd @@ -21,7 +21,7 @@ var _problems: Array = [] func _ready() -> void: -# oracle: design/engineering/test-conventions.md:84(特效截图取证——渲染闸采集组) +# oracle: design/engineering/test-conventions.md:84 (特效截图取证——渲染闸采集组) var args := OS.get_cmdline_user_args() out_dir = args[0] if args.size() >= 1 and args[0] != "" else "user://qa-fx" DirAccess.make_dir_recursive_absolute(out_dir) @@ -108,6 +108,7 @@ func _ready() -> void: func _snap(tag: String) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) await RenderingServer.frame_post_draw var img: Image = get_viewport().get_texture().get_image() if img == null or img.is_empty(): @@ -117,6 +118,7 @@ func _snap(tag: String) -> void: func _fail(msg: String) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) _problems.append(msg) push_error("[fx_shot_probe] FAIL — " + msg) get_tree().quit(1) diff --git a/game/probe/layout_probe.gd b/game/probe/layout_probe.gd index 4fd16f21..cb68fd60 100644 --- a/game/probe/layout_probe.gd +++ b/game/probe/layout_probe.gd @@ -19,7 +19,7 @@ var _est_reads: Dictionary = {} # 逐档 13/14 板推定读数留痕(label func _ready() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:264(战斗屏三区几何与棋盘格边长——分辨率档位组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:264 (战斗屏三区几何与棋盘格边长——分辨率档位组) await get_tree().process_frame var main: Node = load("res://presentation/main.tscn").instantiate() add_child(main) @@ -59,7 +59,7 @@ func _ready() -> void: # 一份不变量断言,逐档代入——代码量与档数无关 func _check_one(label: String, main: Node) -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:264(单档几何断言组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:264 (单档几何断言组) var vr: Rect2 = get_viewport().get_visible_rect() if vr.size != Vector2(VIEWPORTS[0]["size"]) and vr.size.y < 1.0: _problems.append("[%s] 逻辑视口退化 %s" % [label, vr.size]) diff --git a/game/probe/level_map_shot_probe.gd b/game/probe/level_map_shot_probe.gd index 0b34ff25..a201979c 100644 --- a/game/probe/level_map_shot_probe.gd +++ b/game/probe/level_map_shot_probe.gd @@ -11,7 +11,7 @@ extends Node const SEED_L3 := 910212 # 深图固定种子(与 level_map_viewport_probe 同源——图确定性承载) func _ready() -> void: -# oracle: design/engineering/test-conventions.md:84(关卡画面截图取证——载入守卫组) +# oracle: design/engineering/test-conventions.md:84 (关卡画面截图取证——载入守卫组) var args := OS.get_cmdline_user_args() var out_dir := args[0] if args.size() > 0 else "user://" await get_tree().process_frame @@ -45,6 +45,7 @@ func _settle() -> void: func _make_runner(entry: bool, node_id: int): +# oracle: design/engineering/test-conventions.md:84 (判定上报通道——验证函数组) var rng = load("res://core/rng_service.gd").new() rng.new_adventure(SEED_L3) var runner = load("res://core/level_runner.gd").new(get_node("/root/ConfigDB"), rng) @@ -84,6 +85,7 @@ func _deepest_with_outs(screen, runner) -> int: func _shot(out_dir: String, fname: String) -> void: +# oracle: design/engineering/test-conventions.md:84 (判定上报通道——验证函数组) DirAccess.make_dir_recursive_absolute(out_dir) # 落盘目录自建(save_png 对缺目录静默失败——刷新链不预建) var img := get_viewport().get_texture().get_image() var err := img.save_png(out_dir.path_join(fname)) diff --git a/game/probe/level_map_viewport_probe.gd b/game/probe/level_map_viewport_probe.gd index 0b6448f0..6b9a3031 100644 --- a/game/probe/level_map_viewport_probe.gd +++ b/game/probe/level_map_viewport_probe.gd @@ -22,13 +22,14 @@ var _runner # 当前停点的单关 runner(open_choices 驱动随记—— func _check(desc: String, ok: bool) -> void: +# oracle: design/gdd/ux/level-map.md:3 (判定上报通道——验证函数组) _checks += 1 if not ok: _problems.append(desc) func _ready() -> void: -# oracle: design/gdd/ux/level-map.md:3(关卡画面视口跟随——卷轴视口组) +# oracle: design/gdd/ux/level-map.md:3 (关卡画面视口跟随——卷轴视口组) await get_tree().process_frame await get_tree().process_frame var host := Control.new() @@ -61,7 +62,7 @@ func _ready() -> void: ## R1 浅图整幅居中无裁切+画布入视口件承载(画布=视口首子件——setup 注入序) func _probe_shallow_no_crop(screen, vp) -> void: -# oracle: design/gdd/ux/level-map.md:3(浅层不裁切组) +# oracle: design/gdd/ux/level-map.md:3 (浅层不裁切组) _runner = _make_runner_entry(1, SEED_L1) screen.open_choices(_cand_nodes(_runner), _runner) await get_tree().process_frame @@ -80,7 +81,7 @@ func _probe_shallow_no_crop(screen, vp) -> void: ## R5 前置+深图入口停点:锚点=入口组包围盒中心夹紧(spec :101——多入口并列取包围盒居中) func _probe_deep_entry_clamp(screen, vp) -> void: -# oracle: design/gdd/ux/level-map.md:3(深层入口钳制组) +# oracle: design/gdd/ux/level-map.md:3 (深层入口钳制组) _runner = _make_runner_entry(3, SEED_L3) screen.open_choices(_cand_nodes(_runner), _runner) await get_tree().process_frame @@ -174,6 +175,7 @@ func _probe_clamp_bounds_and_columns(screen, vp) -> void: ## R6 拖拽不触发选路提交;阈值另一侧完整点击仍提交(提交语义零改动) func _probe_drag_no_submit(screen, vp) -> void: +# oracle: design/gdd/ux/level-map.md:3 (判定上报通道——验证函数组) # 重建到中段可居中停点(候选=停点出边——候选节点居屏中可拖可达) var stops := _centerable_stops(screen, vp) if stops.size() < 3: @@ -212,6 +214,7 @@ func _probe_drag_no_submit(screen, vp) -> void: ## R2 停点切换后当前节点居中(视口中线投影 x=640±2——视口满屏宽即屏中线) func _probe_follow_anchor(screen, vp) -> void: +# oracle: design/gdd/ux/level-map.md:3 (判定上报通道——验证函数组) var stops := _centerable_stops(screen, vp) if stops.size() < 3: _problems.append("R2 可居中停点不足(=%d)" % stops.size()) @@ -227,6 +230,7 @@ func _probe_follow_anchor(screen, vp) -> void: ## R7 平滑滚动有 tween 中间帧;减动效开=位置即达(画布坐标域判定) func _probe_smooth_scroll_reduced_motion(screen, vp) -> void: +# oracle: design/gdd/ux/level-map.md:3 (判定上报通道——验证函数组) var saved_scale: float = UiKit.motion_scale UiKit.motion_scale = 1.0 var stops := _centerable_stops(screen, vp) @@ -266,6 +270,7 @@ func _probe_smooth_scroll_reduced_motion(screen, vp) -> void: ## R8 指引件可见性与几何(深图超窗——像素级判据②③) func _probe_guidance_chrome(screen, vp) -> void: +# oracle: design/gdd/ux/level-map.md:3 (判定上报通道——验证函数组) var band_l: Control = vp.get_node_or_null(NodePath("FadeL")) var band_r: Control = vp.get_node_or_null(NodePath("FadeR")) var chip: Control = vp.get_node_or_null(NodePath("PanHint")) @@ -297,6 +302,7 @@ func _probe_shallow_guidance_hidden(screen, vp) -> void: ## 入口停点 runner(defer_entry——选路态挂起、候选=入口节点) func _make_runner_entry(level_index: int, seed_val: int): +# oracle: design/gdd/ux/level-map.md:3 (判定上报通道——验证函数组) var rng = load("res://core/rng_service.gd").new() rng.new_adventure(seed_val) var runner = load("res://core/level_runner.gd").new(get_node("/root/ConfigDB"), rng) @@ -307,6 +313,7 @@ func _make_runner_entry(level_index: int, seed_val: int): ## 中段停点 runner(断点续玩重建——图由种子+参数档重生成同图,零 RNG 消耗) func _make_runner_at_stop(level_index: int, seed_val: int, node_id: int): +# oracle: design/gdd/ux/level-map.md:3 (判定上报通道——验证函数组) var rng = load("res://core/rng_service.gd").new() rng.new_adventure(seed_val) var runner = load("res://core/level_runner.gd").new(get_node("/root/ConfigDB"), rng) @@ -381,6 +388,7 @@ func _extreme_node(pos: Dictionary, nodes: Array, first: bool) -> Dictionary: func _finish() -> void: +# oracle: design/gdd/ux/level-map.md:3 (判定上报通道——验证函数组) if _checks == 0: _problems.append("零断言执行(断言数下限闸——三硬闸③)") if _problems.is_empty(): diff --git a/game/probe/t17_defer_probe.gd b/game/probe/t17_defer_probe.gd index 3fab58f2..a535e93f 100644 --- a/game/probe/t17_defer_probe.gd +++ b/game/probe/t17_defer_probe.gd @@ -13,7 +13,7 @@ var _problems: Array = [] func _ready() -> void: -# oracle: design/gdd/ux/battle.md:122(明细带挖掘期收起——T17 视觉扩展时序组) +# oracle: design/gdd/ux/battle.md:122 (明细带挖掘期收起——T17 视觉扩展时序组) await get_tree().process_frame main = load("res://presentation/main.tscn").instantiate() add_child(main) diff --git a/game/probe/type_glow_shot_probe.gd b/game/probe/type_glow_shot_probe.gd index 10f024dc..0a4d3ecb 100644 --- a/game/probe/type_glow_shot_probe.gd +++ b/game/probe/type_glow_shot_probe.gd @@ -30,7 +30,7 @@ var _hero_pos := Vector2i.ZERO func _ready() -> void: -# oracle: design/engineering/test-conventions.md:84(微光截图取证——渲染闸采集组) +# oracle: design/engineering/test-conventions.md:84 (微光截图取证——渲染闸采集组) if DisplayServer.get_name() == "headless": print("[type_glow_shot] FAIL — 本探针必须窗口化运行(headless 无渲染面,截图必空)") get_tree().quit(1) diff --git a/game/probe/ui_click_probe.gd b/game/probe/ui_click_probe.gd index 823383b3..b61804bf 100644 --- a/game/probe/ui_click_probe.gd +++ b/game/probe/ui_click_probe.gd @@ -54,7 +54,7 @@ func _ready() -> void: if main.ui.modals.menu.debug_overlay.visible: _problems.append("调试浮窗 boot 自动开(菜单优先失守)") # ---- 营地购买合成点击路径(选档进档开层→购买→关闭全走真实按钮信号路径; - # oracle: design/gdd/systems/跨局循环/天赋树.md:198(营地购买段——单币购买只扣钥石组) + # oracle: design/gdd/systems/跨局循环/天赋树.md:198 (营地购买段——单币购买只扣钥石组) # 隔离存档换注 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): @@ -192,7 +192,7 @@ func _ready() -> void: if main.ui.modals.camp.scene.visible or not main.ui.screens.start_overlay.visible: _problems.append("营地关闭后未恢复开始层〔句柄子容器批 V1〕") # ---- 选档界面行为走查(迭代 33 卡③):sl5 空槽新档链/sl6 有档槽进档链/sl7 删档二次确认双路径 - # oracle: design/gdd/systems/表现与支撑/存档序列化.md:61(选档走查段——激活态建立组) + # oracle: design/gdd/systems/表现与支撑/存档序列化.md:61 (选档走查段——激活态建立组) # /sl8 消费方分派单口/sl12 动线序不回闪。开层=函数直调(「进入存档」钮归卡② mn3——中间态在案); # 隔离=attach_slot_template 注入命名空间,夹具按槽直写(卡① 注入口)。---- var csel_tpl := "user://smoke_click_probe_savesel_slot_%d.json" @@ -296,7 +296,7 @@ func _ready() -> void: _problems.append("[savesel] 关闭后层未隐藏或开始层未恢复(模态栈单口失守)") # ---- 设置面段(隔离 store 换注禁碰真实 user://settings.cfg;真实按钮信号路径)---- - # oracle: design/gdd/systems/表现与支撑/设置与本地化.md:4(设置面段——最小设置面组) + # oracle: design/gdd/systems/表现与支撑/设置与本地化.md:4 (设置面段——最小设置面组) for p0 in ["user://smoke_click_probe_settings.cfg"]: if FileAccess.file_exists(p0): DirAccess.remove_absolute(p0) @@ -363,7 +363,7 @@ func _ready() -> void: if ProbeUiUtil.find_button(main.ui.modals.menu.settings_overlay, "退出游戏", "prefix") != null: _problems.append("设置面仍含退出游戏按钮(二轮 D1——只在一级菜单出现)") # ---- 生涯页段(入口点击链+关闭回返,真实按钮信号路径;本页只读零写, - # oracle: design/gdd/ux/camp.md:45(生涯页段——同壳同形态组) + # oracle: design/gdd/ux/camp.md:45 (生涯页段——同壳同形态组) # 值断言归冒烟投影段与 ui_struct 结构族,此处只验开合路径与零跳转)---- # 生涯页驱动=函数直调中间态(卡② mn10——careerbtn 已撤,卡④ 笔记本改挂前无 UI 路径) if true: @@ -608,7 +608,7 @@ func _ready() -> void: _run_modal_probes_once() _play_one_action() # ---- 预算耗尽收口(T17 硬锁批适配):选件变强后 probe 可能活过预算不再战败——断点段前提 - # oracle: design/gdd/ux/level-map.md:11(主循环选路段——入口候选组) # (冒险终局面在案)须主动满足。收口驱动:任何停点层逐个推进(复用主循环分支语义)至 + # oracle: design/gdd/ux/level-map.md:11 (主循环选路段——入口候选组) # (冒险终局面在案)须主动满足。收口驱动:任何停点层逐个推进(复用主循环分支语义)至 # level_screen 选路停点→真实放弃二击→终局面。战斗中则继续 autoplay 打完。 if not _done and not main.ui.modals.run.end_overlay.is_open(): var close_guard := 8000 @@ -653,7 +653,7 @@ func _ready() -> void: _play_one_action() # 排播期/Waiting 等待态=自然流逝(演播秒级、锁随队列空解除) # T17 适配:战败或放弃二途皆达终局面(放弃=预算耗尽收口路径——见上),断点段前提不变。 - # oracle: design/gdd/systems/表现与支撑/存档序列化.md:180(断点段——断点域与续玩组) await get_tree().process_frame + # oracle: design/gdd/systems/表现与支撑/存档序列化.md:180 (断点段——断点域与续玩组) await get_tree().process_frame var bp_file := "user://smoke_click_probe_reset.json" var iso_chk = load("res://core/save_manager.gd").new(bp_file) iso_chk.load_from_disk() @@ -684,7 +684,7 @@ func _ready() -> void: # ① 战斗收口断点写盘断言保留(上方——冒险流直调中间态 mn10)。 # ---- 大门两分支断言段(卡④ T5 接收——卡② 移交落点;V3 断言面)---- - # oracle: design/gdd/ux/camp.md:16(大门段——点大门先出确认组) + # oracle: design/gdd/ux/camp.md:16 (大门段——点大门先出确认组) # 驱动=营地场景根点选信号(真实路由)→组合根 _on_camp_object_pressed→确认弹窗。 # 无断点=两出口(是/否);有断点=三出口(set_breakpoint 注入选路停点形——同下方开场行③先例)。 # 判据绑可观测提交面:点大门不直接进冒险(is_adventure 翻转只在 confirmed 后);cancelled 恒= @@ -809,6 +809,7 @@ func _ready() -> void: # ---- 模态/tooltip/刷新链一次性覆盖(真实信号路径驱动) ---- func _run_modal_probes_once() -> void: +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:277 (判定上报通道——验证函数组) # ⓪ 玩家面文案真实入口断言(迭代36 卡A wa1——C 区两段头随战斗常驻) if not _tested_copy and main.ui.battle.info_panel != null and main.ui.battle.info_panel.visible: _tested_copy = true @@ -1051,7 +1052,7 @@ func _click_stop() -> void: # ---- T1 D1:锁期/重放断言(每 run 一次,脚本化场景——演播期豁免的断言化承载) ---- -# oracle: design/gdd/systems/排雷循环/排雷玩法.md:236(锁期/重放段——拒绝与锁组) +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:236 (锁期/重放段——拒绝与锁组) # 锁期断言(排播队列活跃=锁面):注入封印击 → 直落被冻结不受理(封印未置)+ `_locked_click` # 缓存命中且为本注入(「最后一次」语义——注入帧内无并发点击)。 # 重放断言(演播完边沿 pump_ended→_replay_locked_click 重入唯一动作通道):缓存清空 + @@ -1059,6 +1060,7 @@ func _click_stop() -> void: # 前提消失守卫:等重放期间出现停点层/战斗收场(注入时点恰逢终结演播)→ 静默弃测不计 # problem(封印动作不杀伤,正常局不触发;断言实现形态取舍在代拍白名单内)。 func _locktest_tick() -> void: +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:236 (判定上报通道——验证函数组) if _locktest_state == 2: return var settlement = main.run_scope.settlement diff --git a/game/probe/ui_contrast_probe.gd b/game/probe/ui_contrast_probe.gd index 860c9d37..4459417e 100644 --- a/game/probe/ui_contrast_probe.gd +++ b/game/probe/ui_contrast_probe.gd @@ -88,7 +88,7 @@ func _ratio(a: Color, b: Color) -> float: func _ready() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:281(UI 文字对比度机检 ≥4.5:1 无区域例外——对比度组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:281 (UI 文字对比度机检 ≥4.5:1 无区域例外——对比度组) var problems: Array = [] var pairs := _pairs() for p in pairs: diff --git a/game/probe/ui_input_probe.gd b/game/probe/ui_input_probe.gd index 968124c5..8b08983a 100644 --- a/game/probe/ui_input_probe.gd +++ b/game/probe/ui_input_probe.gd @@ -759,6 +759,7 @@ func _push_release(pos: Vector2, btn: int) -> void: func _pre_fail(why: String) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) push_error("[ui_input_probe] FAIL — " + why) print("[ui_input_probe] FAIL — " + why) get_tree().quit(1) diff --git a/game/tests/integration/cross_system_flow_test.gd b/game/tests/integration/cross_system_flow_test.gd index 22c1b78d..5fa4681b 100644 --- a/game/tests/integration/cross_system_flow_test.gd +++ b/game/tests/integration/cross_system_flow_test.gd @@ -20,6 +20,7 @@ var _db func _init() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) _db = ConfigDBScript.new() # 表加载失败不中止(承 G2–G5 同款:表损坏的红落在具体断言上) var load_ok: bool = _db.load_tables("res://data/tables", true) @@ -46,7 +47,7 @@ func _fresh_rng(seed_val: int): # ---- ① RNG 事件日志会话落盘(源 `_initialize` :70,主会话裁决一改判集成—— # 驱动沿源 :60–70 取号序列自持:master 种子 42 → 前置取号 → new_adventure 开日志会话 → 会话内取号)---- func _rng_event_log_session() -> void: -# oracle: design/engineering/architecture/architecture.md:90(事件日志落盘会话组) +# oracle: design/engineering/architecture/architecture.md:90 (事件日志落盘会话组) var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(42) rng.open_stream("board_gen") @@ -61,7 +62,7 @@ func _rng_event_log_session() -> void: # _on_level_finished(victory)+breakpoint_snapshot 取读+clear_breakpoint; # 起局与兑付两步的受理断言留单元宿主(adventure_feats_test),此处纯驱动——前置失败自然落红)---- func _feats_breakpoint_roundtrip() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:180(专长断点附随件往返组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:180 (专长断点附随件往返组) var rt := FeatTable.new() rt.rows = [ {"feat_id": "x1", "display_name": "试一", "rarity": "common", "desc": "测试揭示", "cap": 1, @@ -107,7 +108,7 @@ func _feats_breakpoint_roundtrip() -> void: # level_autoplay 真局摘要 → apply 原语 → 域读数 → 写盘读回保持;临时档 user://smoke_save_integration.json # 段首清场+段尾清理(源 _smoke_save 隔离纪律),绝不碰 user://save.json(红线))---- func _save_summary_integration() -> void: -# oracle: design/gdd/systems/跨局循环/元进度.md:150(摘要集成与钥石只增不减组) +# oracle: design/gdd/systems/跨局循环/元进度.md:150 (摘要集成与钥石只增不减组) var sm_script = load("res://core/save_manager.gd") var path9 := "user://smoke_save_integration.json" # 源 paths[8] if FileAccess.file_exists(path9): @@ -140,7 +141,7 @@ func _save_summary_integration() -> void: # ---- ④ 试玩记录仪(源 `_smoke_playtest_logger` 整套八条,主会话裁决七改判集成—— # PlaytestLogger 挂真实结算流:会话文件/逐结算快照/字段齐备/spawn_count 回归/诊断转储/JSONL 回读)---- func _smoke_playtest_logger() -> void: -# oracle: design/engineering/code-conventions.md:40(试玩日志器跨系统接线组) +# oracle: design/engineering/code-conventions.md:40 (试玩日志器跨系统接线组) print("--- PlaytestLogger(结算快照 JSONL + 诊断转储)---") var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(20260912) diff --git a/game/tests/integration/node_map_determinism_test.gd b/game/tests/integration/node_map_determinism_test.gd index 0ddcd4cb..d00e2215 100644 --- a/game/tests/integration/node_map_determinism_test.gd +++ b/game/tests/integration/node_map_determinism_test.gd @@ -19,6 +19,7 @@ var _bp_path := "user://smoke_node_map_save.json" func _init() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) _db = load("res://core/config_db.gd").new() # 表加载失败不中止(承 G2/G3/G4/G5 同款:表损坏的红落在具体断言上) var load_ok: bool = _db.load_tables("res://data/tables", true) @@ -33,7 +34,7 @@ func _init() -> void: # ---- 关卡节点图生成·确定性承载断言面 ---- func _smoke_generated_map_determinism() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:134(起关/选路/断点重生成同图组) +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:134 (起关/选路/断点重生成同图组) # ① 纯函数复现:图 = f(参数档, 种子)——同档同种子两次产图逐位同图,换种子必变图 var gen = NodeMapGenerator.new(_fresh_rng(910001)) var params2: Dictionary = _db.run.level_gen_params.row_by_level_index(2) diff --git a/game/tests/integration/save_rng_roundtrip_test.gd b/game/tests/integration/save_rng_roundtrip_test.gd index ade5b288..d2bda306 100644 --- a/game/tests/integration/save_rng_roundtrip_test.gd +++ b/game/tests/integration/save_rng_roundtrip_test.gd @@ -20,6 +20,7 @@ var _disk: String func _init() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) _disk = ProjectSettings.globalize_path(SAVE_PATH) _clear_disk() _db = load("res://core/config_db.gd").new() as ConfigDb @@ -35,7 +36,7 @@ func _init() -> void: # ---- 用例一:盘上往返保真——写档再读回,断点逐键零漂移 ---- func _test_disk_roundtrip_preserves_breakpoint() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:180(存档⇄RNG 快照往返——断点域逐位组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:180 (存档⇄RNG 快照往返——断点域逐位组) var rng := RngServiceScript.new() var sm := SaveManagerScript.new(SAVE_PATH) var adr := AdventureRunnerScript.new(_db, rng) @@ -66,7 +67,7 @@ func _test_disk_roundtrip_preserves_breakpoint() -> void: # ---- 用例二:旧版本档经迁移链后仍可续玩(单测不覆盖的跨系统集成面)---- func _test_old_version_save_migrates_and_resumes() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:179(旧档迁移链读回续玩组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:179 (旧档迁移链读回续玩组) var rng := RngServiceScript.new() var sm := SaveManagerScript.new(SAVE_PATH) var adr := AdventureRunnerScript.new(_db, rng) diff --git a/game/tests/smoke_boot.gd b/game/tests/smoke_boot.gd index eed5e76e..40b4f767 100644 --- a/game/tests/smoke_boot.gd +++ b/game/tests/smoke_boot.gd @@ -16,7 +16,7 @@ var _checks: int = 0 func check(cond: bool, label: String) -> void: -# oracle: game/tests/README.md:366(冒烟宿主判据通道——存活检查组) +# oracle: design/engineering/architecture/architecture.md:10 (测试层级四级——冒烟存活检查组) _checks += 1 if cond: print(" [PASS] " + label) @@ -35,7 +35,7 @@ func _ready() -> void: # 开机前置面:autoload 注册与资源可加载(挂主屏之前先查,失败时主屏断言整段跳过) func _check_autoloads() -> void: -# oracle: game/tests/README.md:366(autoload 在位组) +# oracle: design/engineering/architecture/architecture.md:10 (测试层级四级——冒烟存活检查组) for autoload_name in ["ConfigDB", "RngService", "SaveManager", "MetaProgression"]: var node: Node = get_node_or_null(NodePath("/root/" + autoload_name)) check(node != null, "autoload %s 在位" % autoload_name) @@ -64,7 +64,7 @@ func _boot_main_scene() -> Node: # 主屏存活面:组合根装配句柄在位(main.X 一级句柄契约,探针挂载假设的启动侧证明) func _check_main_scene(main: Node) -> void: -# oracle: game/tests/README.md:366(主屏可达组) +# oracle: design/engineering/architecture/architecture.md:10 (测试层级四级——冒烟存活检查组) check(main != null and main.is_inside_tree(), "主屏场景已实例化并在树") if main == null: return diff --git a/game/tests/system_test.gd b/game/tests/system_test.gd index b98c626a..c9c951b1 100644 --- a/game/tests/system_test.gd +++ b/game/tests/system_test.gd @@ -33,6 +33,7 @@ func _initialize() -> void: # (自 game/smoke/smoke_all.gd 剪切迁入——断言 label 逐字原样;G12 两套调用不随迁, # 归 source_guard_test.gd,断言迁移批 B G1) func _split_tail() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) await process_frame await process_frame var autoload_ok: bool = get_root().get_node_or_null("/root/ConfigDB") != null and get_root().get_node_or_null("/root/SaveManager") != null @@ -51,6 +52,7 @@ func _split_tail() -> void: # ---- 三屏场景化断言(V2——独立实例化+关键节点在位+组合根树序/z 序保序)---- # (自 game/smoke/smoke_all.gd 剪切迁入——label 与 cond 逐字原样,断言迁移批 B G1) func _smoke_scene_split() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) print("--- 迭代27 T1 三屏场景化(V2:屏壳独立实例化+组合根装配保序)---") # ① 三屏壳独立实例化(F6 等价——headless 直挂;视图代码构建在屏壳 _ready) var menu: Node = load("res://presentation/scenes/menu_screen.tscn").instantiate() @@ -147,6 +149,7 @@ func _count_visible_buttons(node: Node) -> int: # ---- boot 链路时序后置条件(启动态六断言;只立行为可判断言,不造假时序)---- func _smoke_boot_chain() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) print("--- 迭代28 T2 boot 链路时序后置条件(V2:六断言)---") var main: Node = load("res://presentation/main.tscn").instantiate() root.add_child(main) @@ -211,6 +214,7 @@ func _smoke_boot_chain() -> void: func _smoke_run_lifecycle() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) print("--- 迭代27 T1 会话物化(V3:两连局复位+脏状态不残留)---") var main: Node = load("res://presentation/main.tscn").instantiate() root.add_child(main) @@ -268,6 +272,7 @@ func _smoke_run_lifecycle() -> void: # ---- d6/d7 批量模拟互斥守卫(wd6/wd7——白盒置态直调入口,以守卫早退的可见后果为断言面)---- func _smoke_sim_guards() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) print("--- 卡① T2:批量模拟互斥两守卫(d6/d7)---") var main: Node = load("res://presentation/main.tscn").instantiate() root.add_child(main) @@ -341,6 +346,7 @@ func _face_snapshot(main: Node) -> Dictionary: # 阶段面断言:adv/run/set=alive|null|both(会话三面存活态);恒活面每阶段必查; # 现值回调与 run_scope 成员必须同源(回调链无悬挂铁证);extra=阶段附加判据。 func _stage_faces(main: Node, tag: String, adv: String, run: String, set: String, extra: Dictionary = {}) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var snap := _face_snapshot(main) var bad := "" for k in ["bonus_meta", "bonus_save", "camp_meta", "camp_save", "rp_log", "rp_stage", "rp_board_zone", "rp_fx", "rp_board"]: @@ -409,7 +415,7 @@ func _face_liveness(name: String, v, want: String) -> String: #(level_started→choices_presented 同步到达,无可观测中间态)——合并为 V3b 一处断言。 # (自 game/smoke/smoke_all.gd 剪切迁入——label 与 cond 逐字原样,断言迁移批 B G1) func _smoke_lifecycle_matrix() -> void: -# oracle: design/gdd/systems/冒险循环/冒险结构.md:284(生命周期矩阵——三关序列组) +# oracle: design/gdd/systems/冒险循环/冒险结构.md:284 (生命周期矩阵——三关序列组) print("--- 迭代28 T3 生命周期存活性矩阵(V3:九阶段×五引用面)---") var main: Node = load("res://presentation/main.tscn").instantiate() root.add_child(main) diff --git a/game/tests/unit/battle_settlement/damage_controller_test.gd b/game/tests/unit/battle_settlement/damage_controller_test.gd index 250a3cda..8807bd03 100644 --- a/game/tests/unit/battle_settlement/damage_controller_test.gd +++ b/game/tests/unit/battle_settlement/damage_controller_test.gd @@ -71,7 +71,7 @@ func _row_by_display_prefix(prefix: String) -> Dictionary: # ---- 五配方一次全流程 + 双跑逐位复现 ---- func _run_recipe_sequence(db) -> Array: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:362(五段全序——配方序列组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:362 (五段全序——配方序列组) _rows = [] var h = _harness(db) var units = h.units @@ -178,7 +178,7 @@ func _run_recipe_sequence(db) -> Array: func _test_five_recipes_and_replay(db) -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:363(同种子回放逐行相同组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:363 (同种子回放逐行相同组) var run1: Array = _run_recipe_sequence(db) Kit.check("五配方序列产出 5 行伤害行", run1.size() == 5) var run2: Array = _run_recipe_sequence(db) @@ -188,7 +188,7 @@ func _test_five_recipes_and_replay(db) -> void: # ---- A 模式(开单即结——回切位) ---- func _test_policy_immediate_mode(db) -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:362(结算策略即时面组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:362 (结算策略即时面组) _rows = [] var h = _harness(db) if not h.spawn_ok: @@ -204,7 +204,7 @@ func _test_policy_immediate_mode(db) -> void: # ---- 来源敌死亡:队列中未结单据作废(死亡即不动手) ---- func _test_source_death_void(db) -> void: -# oracle: design/gdd/systems/战斗循环/敌人系统.md:133(摇定后兑现前被杀本拍作废组) +# oracle: design/gdd/systems/战斗循环/敌人系统.md:133 (摇定后兑现前被杀本拍作废组) _rows = [] var h = _harness(db) if not h.spawn_ok: @@ -238,7 +238,7 @@ func _unit_fixture() -> Dictionary: func _test_identical_content_dual_enemy(db: ConfigDb) -> void: -# oracle: design/gdd/systems/战斗循环/敌人系统.md:303(双敌同内容顺位组) +# oracle: design/gdd/systems/战斗循环/敌人系统.md:303 (双敌同内容顺位组) var a := _unit_fixture() var b := _unit_fixture() Kit.check("前置:双敌字典内容全同且非同一实例", a == b and not is_same(a, b)) @@ -268,6 +268,7 @@ func _test_identical_content_dual_enemy(db: ConfigDb) -> void: # d12 产发端增键:目标身份随行/随载荷下发(同名敌按 id 精确解析的产发半) func _test_target_id_payload(db: ConfigDb) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) _rows = [] var h = _harness(db) if not h.spawn_ok: @@ -290,6 +291,7 @@ func _test_target_id_payload(db: ConfigDb) -> void: func _test_requires_gate_and_zero(db) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) _rows = [] var h = _harness(db) if not h.spawn_ok: @@ -316,6 +318,7 @@ func _test_requires_gate_and_zero(db) -> void: # ---- 主角倒下:flush 余单全部作废(_halted 终止) ---- func _test_hero_death_halt(db) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) _rows = [] var h = _harness(db) if not h.spawn_ok: @@ -333,6 +336,7 @@ func _test_hero_death_halt(db) -> void: # ---- AC 合流:override 入参 / 表值兜底 / ac 型状态叠层(不入池) ---- func _test_ac_merge(db) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) _rows = [] var h = _harness(db) if not h.spawn_ok: @@ -360,6 +364,7 @@ func _test_ac_merge(db) -> void: # ---- 池乘区收口:池内加算 → clamp;ac 型不入池 ---- func _test_pool_clamp(db) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) _rows = [] var h = _harness(db) if not h.spawn_ok: @@ -417,6 +422,7 @@ func _test_pool_clamp(db) -> void: # ---- 个体池读数 / 个体 AC 合流(增益状态 v1.5——敌方状态个体化批)---- func _test_pool_consumption_per_unit(db) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var h = _harness(db, 3) # depth 3 = 混编行集(熊地精 1 + 地精 1–2,最少 2 只——个体对照面需 ≥2 敌) if not h.spawn_ok: return @@ -436,6 +442,7 @@ func _test_pool_consumption_per_unit(db) -> void: func _test_defender_ac_per_unit(db) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var h = _harness(db, 3) if not h.spawn_ok: return diff --git a/game/tests/unit/battle_settlement/damage_math_test.gd b/game/tests/unit/battle_settlement/damage_math_test.gd index e5d9114f..8e468109 100644 --- a/game/tests/unit/battle_settlement/damage_math_test.gd +++ b/game/tests/unit/battle_settlement/damage_math_test.gd @@ -12,7 +12,7 @@ var db func _init() -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:360(伤害公式宿主——装载组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:360 (伤害公式宿主——装载组) db = ConfigDBScript.new() var load_ok: bool = db.load_tables("res://data/tables", true) Kit.check("前置:settlement 表加载零 error", load_ok and db.diagnostics_count("error") == 0) @@ -31,7 +31,7 @@ func _floor_val() -> int: # ---- F2 乘区:池内加算 → 池间乘算 → floor(单一取整规则)---- func _test_pool_damage() -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:360(池伤害公式组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:360 (池伤害公式组) var d := _floor_val() + 9 # 表值推导的任意正探针量(非玩法行值) Kit.check("中性双池 (0,0) 原样透传", DamageMathScript.pool_damage(d, 0, 0) == d) Kit.check("负敌方池压低不增高", DamageMathScript.pool_damage(d, 0, int(db.combat.settlement.core.pool_clamp_lo)) <= d) @@ -44,7 +44,7 @@ func _test_pool_damage() -> void: # ---- 克制分量:空桶不吃修正恒 0;落地下限保底([1,+∞) 全来源)---- func _test_counter_component() -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:360(计数器分量组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:360 (计数器分量组) var floor_v := _floor_val() Kit.check("空桶(点数≤0)恒 0 不吃修正", DamageMathScript.counter_component(0, floor_v, floor_v) == 0 and DamageMathScript.counter_component(-1, 5, floor_v) == 0) @@ -56,7 +56,7 @@ func _test_counter_component() -> void: # ---- 掷点折扣查档(纯函数):满阈值恒全额;档位边界/末档语义与表数组一致 ---- func _test_roll_discount_percent() -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:360(乘区折扣组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:360 (乘区折扣组) var threshold := 10 # 查档探针阈值(夹具值——档位参数本身全部来自表) var bounds: Array = db.combat.settlement.damage_roll.roll_tier_bounds var discounts: Array = db.combat.settlement.damage_roll.roll_tier_discounts @@ -81,7 +81,7 @@ func _test_roll_discount_percent() -> void: # ---- 吃掷点分量算术:折扣→(暴击)→floor→+克制修正(单一取整链)---- func _test_rolled_component() -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:360(掷点分量组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:360 (掷点分量组) var base := float(_floor_val() + 7) # 表值推导探针基线 var crit_mult: int = int(db.combat.settlement.damage_roll.crit_multiplier) Kit.check("满额折扣无暴击 = floor(基线) + 修正 0", DamageMathScript.rolled_component(base, 100, false, crit_mult, 0) == int(floor(base))) diff --git a/game/tests/unit/battle_settlement/effect_port_test.gd b/game/tests/unit/battle_settlement/effect_port_test.gd index a8948a1e..9394c55c 100644 --- a/game/tests/unit/battle_settlement/effect_port_test.gd +++ b/game/tests/unit/battle_settlement/effect_port_test.gd @@ -19,7 +19,7 @@ var _db func _init() -> void: -# oracle: design/engineering/architecture/architecture.md:144(效果端口宿主——装载组) +# oracle: design/engineering/architecture/architecture.md:144 (效果端口宿主——装载组) _db = ConfigDBScript.new() var load_ok: bool = _db.load_tables("res://data/tables", true) Kit.check("前置:表加载零 error", load_ok and _db.diagnostics_count("error") == 0) @@ -54,7 +54,7 @@ func _hero_attack_value(rows: Array) -> int: # ---- V1 端口单实例与真实发射路由 ---- func _smoke_effect_port_wiring() -> void: -# oracle: design/engineering/architecture/architecture.md:144(端口单实例与六 Callable 路由组) +# oracle: design/engineering/architecture/architecture.md:144 (端口单实例与六 Callable 路由组) print("--- 效果端口:装配链单实例+真实发射路由 ---") # 充能跑(蓄力周转 charge_rotation 在册——attack_commit 订阅行 attack_bonus per 蓄力周转计数器) var orch_c = _orch(TEST_SEED) @@ -88,7 +88,7 @@ func _smoke_effect_port_wiring() -> void: # ---- V2 业务类零引擎直连(源码契约锚——theme_projection_test 源码锚惯例)---- func _test_business_classes_engine_free() -> void: -# oracle: design/engineering/architecture/architecture.md:144(业务类零引擎直连组) +# oracle: design/engineering/architecture/architecture.md:144 (业务类零引擎直连组) print("--- 效果端口:业务类零引擎直连源码锚 ---") for path in ["res://core/damage_controller.gd", "res://core/action_economy.gd"]: var src := FileAccess.get_file_as_string(path) @@ -100,7 +100,7 @@ func _test_business_classes_engine_free() -> void: # ---- V3 伤害域事实面闭集(合成行两对照——damage_taken 真实单据流)---- func _test_biz_fact_face_closed() -> void: -# oracle: design/engineering/architecture/architecture.md:144(闭面四键 biz_fact 组) +# oracle: design/engineering/architecture/architecture.md:144 (闭面四键 biz_fact 组) print("--- 效果端口:业务发射事实面闭集 ---") var orch = _orch(TEST_SEED) Kit.check("V3 begin_battle 受理", orch.begin_battle(_enc([]))) diff --git a/game/tests/unit/battle_settlement/extended_row_violation_test.gd b/game/tests/unit/battle_settlement/extended_row_violation_test.gd index 827eed8b..fd3ac2c5 100644 --- a/game/tests/unit/battle_settlement/extended_row_violation_test.gd +++ b/game/tests/unit/battle_settlement/extended_row_violation_test.gd @@ -11,7 +11,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:199(扩展行必载 effect_id——加载致命组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:199 (扩展行必载 effect_id——加载致命组) var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): push_error("[extended_row_violation_test] 表加载失败") diff --git a/game/tests/unit/battle_settlement/refresh_feats_test.gd b/game/tests/unit/battle_settlement/refresh_feats_test.gd index 958427cb..01fc0c08 100644 --- a/game/tests/unit/battle_settlement/refresh_feats_test.gd +++ b/game/tests/unit/battle_settlement/refresh_feats_test.gd @@ -154,7 +154,7 @@ func _seal_direct_with_expansion(orch) -> Vector2i: # 四条真实路径(敌方攻击/危险格/错误封印/地形)逐路驱动:每条至少一张主角承伤单据在案, # 且承伤计数器 == 主角承伤单据行数(每单据恰发射一次的全量判据——重复发射即计数器>行数)。 func test_all_hero_damage_paths_emit_once() -> void: -# oracle: design/gdd/systems/冒险循环/奇物.md:465(换图生存:全局固定减伤全伤害路径恰一次组) +# oracle: design/gdd/systems/冒险循环/奇物.md:465 (换图生存:全局固定减伤全伤害路径恰一次组) print("--- V5 全局 damage_taken:四路径逐路恰一次 ---") # ① 敌方攻击路径(Boss 战零挖掘连停三轮——干净样本:零地形零资源单据;多轮保证伤害技在案) var orch1 = _orch(46001) @@ -224,7 +224,7 @@ func _plan_seal(orch, target: Vector2i) -> Dictionary: # 同一伤害不得出现两次消费(重复发射=计数器>行数):敌方路径与地形路径两样本逐位核对—— # 地形单据带 hero_damage_consumed 标记,战斗段末 _resolve_board_flat_hero 跳过二次发射由此钉住。 func test_no_duplicate_damage_taken_event() -> void: -# oracle: design/gdd/systems/冒险循环/奇物.md:465(受击事件零重复组) +# oracle: design/gdd/systems/冒险循环/奇物.md:465 (受击事件零重复组) print("--- V5 全局 damage_taken:无重复消费 ---") var orch1 = _orch(46011) var rows1 := _collect_hero_rows(orch1) @@ -266,7 +266,7 @@ func _auto_dig(orch) -> void: # V2 矿脉储能:受理的付费挖格 RAP 恰 +1、AP 按表扣、板资源不变 func test_reserve_on_accepted_dig() -> void: -# oracle: design/gdd/systems/排雷循环/行动经济.md:256(换图基座:挖格产 RAP 组) +# oracle: design/gdd/systems/排雷循环/行动经济.md:256 (换图基座:挖格产 RAP 组) print("--- V2 矿脉储能:付费挖格产 RAP ---") var orch = _orch(46021) Kit.check("V2 前置:战斗受理", orch.begin_battle(_enc(["vein_reserve"]))) @@ -304,7 +304,7 @@ func _drain_round_rap_accounting(orch) -> bool: # V3 省力周转:折价门槛与扣费(can 与执行同源;base 8→扣 4) func test_refresh_discount_gate_and_charge() -> void: -# oracle: design/gdd/systems/排雷循环/行动经济.md:256(刷新折扣门控与充能组) +# oracle: design/gdd/systems/排雷循环/行动经济.md:256 (刷新折扣门控与充能组) print("--- V3 省力周转:折价门槛与扣费 ---") var orch = _orch(46022) Kit.check("V3 前置:战斗受理", orch.begin_battle(_enc(["easy_swap"]))) @@ -326,7 +326,7 @@ func test_refresh_discount_gate_and_charge() -> void: # V3 双基座叠加:挖格产 RAP 与刷新折价同场生效 func test_double_base_stack() -> void: -# oracle: design/gdd/systems/冒险循环/奇物.md:465(双基座叠加组) +# oracle: design/gdd/systems/冒险循环/奇物.md:465 (双基座叠加组) print("--- V3 双基座叠加 ---") var orch = _orch(46023) Kit.check("V3 前置:战斗受理", orch.begin_battle(_enc(["vein_reserve", "easy_swap"]))) @@ -343,7 +343,7 @@ func test_double_base_stack() -> void: # V12(refresh_feats 侧):无专长基线——挖格零产 RAP、刷新按表基线扣、AP 保留、上限照旧 func test_no_feats_baseline() -> void: -# oracle: design/gdd/systems/冒险循环/奇物.md:465(零专长基线组) +# oracle: design/gdd/systems/冒险循环/奇物.md:465 (零专长基线组) print("--- V12 无专长基线(refresh_feats 侧) ---") var orch = _orch(46024) Kit.check("V12 前置:战斗受理", orch.begin_battle(_enc([]))) @@ -379,7 +379,7 @@ func _br_count(orch) -> int: # V4 成功事实只在新板就位后发射:成功恰一次;非 Active/每轮上限/RAP 不足三拒面全零事实零换图 func test_board_refresh_fact_only_on_success() -> void: -# oracle: design/gdd/systems/排雷循环/行动经济.md:256(弃图刷新事实面仅成功态组) +# oracle: design/gdd/systems/排雷循环/行动经济.md:256 (弃图刷新事实面仅成功态组) print("--- V4 成功刷新事实:拒绝零事实 ---") _install_br_probe() var orch = _orch(46031) @@ -414,7 +414,7 @@ func test_board_refresh_fact_only_on_success() -> void: # V10 矿道红利:每次成功刷新 escrow 恰 +1 且 fx_grant_gp 行在案;拒绝零变化 func test_mine_profit_gp() -> void: -# oracle: design/gdd/systems/冒险循环/奇物.md:465(换图资源:刷新固定 GP 收益组) +# oracle: design/gdd/systems/冒险循环/奇物.md:465 (换图资源:刷新固定 GP 收益组) print("--- V10 矿道红利:刷新固定 GP ---") var orch = _orch(46032) var gp_rows := {"n": 0} @@ -461,7 +461,7 @@ func _damage_rows_by_source(rows: Array, source: String) -> Array: # V6 石层缓冲:全局固定减伤(危险格 pierce 8→6 两档钉死:单刷减 2·同轮多刷不叠加·未刷新轮不减; # 地形路径减后值=max(下限, effect_value−2)——含下限保持;敌方路径照常单次发射) func test_stone_mitigation_all_damage() -> void: -# oracle: design/gdd/systems/冒险循环/奇物.md:465(全局减伤全覆盖组) +# oracle: design/gdd/systems/冒险循环/奇物.md:465 (全局减伤全覆盖组) print("--- V6 石层缓冲:全局固定减伤 ---") # S1 同轮双刷 → 危险格 pierce 8 减 2=6(叠加即 4——多刷不增钉死) var orch1 = _orch(46041) @@ -517,7 +517,7 @@ func test_stone_mitigation_all_damage() -> void: # V9 坑道小憩:轮末合计回复(白盒预置承载上限 3——计数器直改属数据面注入; # 自然累计 2 与满血未生效两形态分战场钉死) func test_rest_rotation_cap_and_clear() -> void: -# oracle: design/gdd/systems/冒险循环/奇物.md:465(轮末恢复 cap 与清账组) +# oracle: design/gdd/systems/冒险循环/奇物.md:465 (轮末恢复 cap 与清账组) print("--- V9 坑道小憩:轮末恢复 ---") # R1 白盒预置 3 层 + 刷新闸(when<3 拒第 4 层)→ 停手回复 min(3, 缺血)——护甲降档保缺血 ≥3 var orch1 = _orch(46051) @@ -575,7 +575,7 @@ func test_rest_rotation_cap_and_clear() -> void: # V8 蓄力周转:当轮攻击消费全部层数(上限 3 闸=白盒预置;战斗新建自然清空) func test_charge_layers_consumed_same_round() -> void: -# oracle: design/gdd/systems/冒险循环/奇物.md:465(充能当轮消耗组) +# oracle: design/gdd/systems/冒险循环/奇物.md:465 (充能当轮消耗组) print("--- V8 蓄力周转:攻击消费层 ---") var orch1 = _orch(46061) var rows1 := _collect_damage_rows(orch1) @@ -602,7 +602,7 @@ func test_charge_layers_consumed_same_round() -> void: # V7 崩壁冲击:延迟群伤单(刷新时点零伤害行——战斗段末按存活目标结账) func test_blast_defers_to_combat_segment() -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:362(刷新群伤让位战斗段组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:362 (刷新群伤让位战斗段组) print("--- V7 崩壁冲击:延迟群伤 ---") var orch = _orch(46071) var rows := _collect_damage_rows(orch) @@ -621,7 +621,7 @@ func test_blast_defers_to_combat_segment() -> void: # 七件 validate/在册/稀有度 cap 对表/跨表计数器引用闭合/desc 禁词 func test_seven_feats_validate_and_pool() -> void: -# oracle: design/gdd/systems/冒险循环/奇物.md:465(换图系七件校验与池组) +# oracle: design/gdd/systems/冒险循环/奇物.md:465 (换图系七件校验与池组) print("--- V11 七件数据与池 ---") var seven := {"vein_reserve": "excellent", "easy_swap": "excellent", "wall_blast": "excellent", "charge_rotation": "excellent", "stone_mitigation": "common", "tunnel_rest": "common", "mine_profit": "rare"} diff --git a/game/tests/unit/battle_settlement/roll_multiplier_test.gd b/game/tests/unit/battle_settlement/roll_multiplier_test.gd index 3096787f..50c6ff17 100644 --- a/game/tests/unit/battle_settlement/roll_multiplier_test.gd +++ b/game/tests/unit/battle_settlement/roll_multiplier_test.gd @@ -19,7 +19,7 @@ var _db func _init() -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:360(掷点与乘区宿主——装载组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:360 (掷点与乘区宿主——装载组) _db = ConfigDBScript.new() # 表加载失败不中止(承 G2/G3 同款:表损坏的红落在具体断言上—— # 诊断在此展开,后续断言按坏表实况逐条验红;collect_only=true 下成员照常赋值可评) @@ -44,7 +44,7 @@ func _init() -> void: # 受理后不变量(encounter 受理后只读)。攻击单 base_value 贯通由 _smoke_damage_types 的 # hero_atk_val=100 全链路行值承载(同夹具既有覆盖——派生读在攻击链上工作即行值随 override 走)---- func _smoke_hero_atk_derived() -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:360(英雄攻击派生组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:360 (英雄攻击派生组) var rng_a = load("res://core/rng_service.gd").new() rng_a.set_master_seed(4242) var s_a = load("res://core/battle_orchestrator.gd").new(_db, rng_a) @@ -67,7 +67,7 @@ func _smoke_hero_atk_derived() -> void: # → heavy 伤害 == light −1、ward == light +1(要求基线伤害 ≥ 2——地板 1 会吞 −1 位移)。 # 承伤位移红线(卡片 §8 L3):全局位移只允许 ±1 量级——非此量级 = 矩阵消费面有未盘点的第二落点(停机)。 func _smoke_enemy_attack_type() -> void: -# oracle: design/gdd/systems/战斗循环/敌人系统.md:295(敌攻击类型行集组) +# oracle: design/gdd/systems/战斗循环/敌人系统.md:295 (敌攻击类型行集组) print("--- 敌方攻击类型轴(迭代 24 N3)---") # ① 表列:20 行全填 normal(N3 全填不做差异化——Q9) var at_ok := true @@ -126,7 +126,7 @@ func _smoke_enemy_attack_type() -> void: # ---- 护甲等级掷点·行为面(折扣档分布 / nat20 暴击 / 伤害下限 / 棋盘来源必中)---- func _smoke_armor_roll() -> void: -# oracle: design/gdd/systems/战斗循环/增益状态.md:254(护甲掷点与叠层合并组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:254 (护甲掷点与叠层合并组) print("--- 护甲等级掷点(查档纯函数 + 暴击 + 伤害下限 + AC12 分布 + 棋盘必中)---") # ① 查档纯函数:全掷点域逐位对照(AC10 / AC12)+ EV 锚(AC10 期望减免 21.25% —— registry 参考数) var expect_ac10 := {100: 11, 75: 3, 50: 4, 25: 2} # 掷 10-20 全额 / 7-9 / 3-6 / 1-2 @@ -345,6 +345,7 @@ func _auto_play_round(settlement, out: Dictionary) -> void: # 基线构成:基线 100——hero 攻击类型=normal(锻造工坊配置默认值, # hero.tres 无两轴字段)对轻甲中性 0 修正(目标 = L1 地精轻甲;AC 0 恒全额非暴击种子)。 func _smoke_pool_wiring() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) print("--- 主角乘区接线 + 硬化折半方向 ---") var base_row := _hero_attack_row_with({}, 100, 20260918) var up_row := _hero_attack_row_with({"effects": ["attack_up"]}, 100, 20260918) @@ -386,6 +387,7 @@ func _hero_attack_row_with(opts: Dictionary, hero_atk_val: int, seed_val: int) - # ---- 攻击类型 × 护甲克制 + 标错惩罚冒烟(护甲快照/克制矩阵/充能/反噬三选一)---- func _smoke_damage_types() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) print("--- 攻击类型 × 护甲克制 + 标错惩罚 ---") # ① 护甲类型快照传播(spawn 行值 → 单位字典) var enemy_system = load("res://core/unit_container.gd").new(_db) @@ -480,6 +482,7 @@ func _find_seal_target(minesweeper, want_mine: bool) -> Dictionary: # d_tick = max(damage_floor, pool_damage(floor(基线×档位%), 0, 0)),档位读数随行重建可归因)---- func _smoke_attack_chain_fresh_pool() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) print("--- 战斗结算·fresh 池攻击链回归(Bug#2·掷点口径)---") var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(20260913) diff --git a/game/tests/unit/battle_settlement/round_flow_skill_pool_test.gd b/game/tests/unit/battle_settlement/round_flow_skill_pool_test.gd index 3f2fe528..d3a7a1ef 100644 --- a/game/tests/unit/battle_settlement/round_flow_skill_pool_test.gd +++ b/game/tests/unit/battle_settlement/round_flow_skill_pool_test.gd @@ -22,7 +22,7 @@ var _db func _init() -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:360(轮内流与技能池宿主——装载组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:360 (轮内流与技能池宿主——装载组) _db = ConfigDBScript.new() # 表加载失败不中止(承 G2/G3/G4/G5 同款:表损坏的红落在具体断言上—— # 诊断在此展开,后续断言按坏表实况逐条验红;collect_only=true 下成员照常赋值可评) @@ -48,7 +48,7 @@ func _init() -> void: # ---- 完整战斗回放(自动玩家,确定性)——回放断言:同种子两遍步骤流逐行相同 ---- func _smoke_full_battle(L: int, D: int, label: String) -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:362(全战斗回放——五段全序组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:362 (全战斗回放——五段全序组) print("--- 完整战斗回放:%s ---" % label) var run1 = _run_battle(L, D) var run2 = _run_battle(L, D) @@ -83,7 +83,7 @@ func _smoke_full_battle(L: int, D: int, label: String) -> void: func _run_battle(L: int, D: int, axes: Dictionary = {}) -> Dictionary: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:362(战斗驱动组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:362 (战斗驱动组) # 每遍全新 RngService(同 master 种子)——回放断言的隔离前提(地图战斗资源 AC"两套全新 RngService+地图战斗资源"同款) var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(42) @@ -148,7 +148,7 @@ func _auto_play_round(settlement, out: Dictionary) -> void: # ---- 行动经济·轮内刷新冒烟(方案 A:Active 相位当场换图继续挖)---- func _smoke_active_refresh() -> void: -# oracle: design/gdd/systems/排雷循环/行动经济.md:262(停手转存储备与轮内刷新组) +# oracle: design/gdd/systems/排雷循环/行动经济.md:262 (停手转存储备与轮内刷新组) print("--- 行动经济·轮内刷新(方案 A)---") var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(20260912) @@ -255,7 +255,7 @@ func _active_refresh_replay() -> Array: # ---- 遭遇随机化冒烟(难度曲线与Boss Core Rule 8:区间骰/encounter 流/可回放/空表定值路径)---- func _smoke_encounter_roll() -> void: -# oracle: design/gdd/systems/战斗循环/敌人系统.md:296(遭遇区间骰——摇号确定性组) +# oracle: design/gdd/systems/战斗循环/敌人系统.md:296 (遭遇区间骰——摇号确定性组) print("--- 遭遇随机化(unit_count 区间骰)---") var counts: Array = [] for i in range(20): @@ -390,6 +390,7 @@ func _encounter_replay(seed_val: int) -> Array: # 五段全序断言(战斗结算 验收"五段全序"+ 行型封闭 10 类):逐轮行相位序 = 授予 → 增益/减益 → 战斗 → 衰减 → 判定。 func _smoke_settlement_segments() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) print("--- 五段全序 + 行型封闭 ---") Kit.check("segment_order 五段冻结在位(表值 = 拍板序恒等)", Array(_db.combat.settlement.segment_order) == SettlementTable.FROZEN_SEGMENT_ORDER @@ -508,6 +509,7 @@ func _smoke_skill_pool() -> void: # ① 数据面:技能表行集 + 普攻锁死 + 建议池行值 + 空池不可能(结构断言) func _smoke_skill_pool_data() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) Kit.check("技能表十六行(普攻/突刺/蓄力/重击/硬化 + 撕咬/毒爆/蛛网束缚 + 大地脉动 + 震地怒击/遏毒/岩崩 + 毒吐/盾击——前三批 + Boss 半血解锁技三行〔迭代14④ T5〕+ 普通敌错峰两行〔迭代 24 N2〕+ 触发条件批示范两行〔孤注守势/趁隙偷袭〕)", _db.combat.skill.rows.size() == 16) var basic: Dictionary = _db.combat.skill.row_by_id("attack") Kit.check("普攻行:倍率恒 1 · 冷却恒 0(域校验锁死——池恒非空的结构前提)", @@ -722,6 +724,7 @@ func _fresh_rng(seed_val: int): # 单敌轨迹不独立复放——轨迹取数与其它流交错,无法脱离全序重建; # 同种子全战斗逐位复现由 ② 全对拍承载,单点定位归事件日志。 func _smoke_skill_pool_replay_independence() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var seed_val := -1 for s in range(1, 60): var seqs := _record_pool_trajectories(s, 1) @@ -775,6 +778,7 @@ func _record_pool_trajectories(seed_val: int, rounds: int) -> Dictionary: # 2026-10-28 重锚 [0.82, 1.02](照酋长先例 ±0.10 绝对幅度,中值取理论稳态 0.92;旧带 [1.00,1.20] 系触发器前 # 唯一特殊技=突刺的池结构下登记,随池构成换代作废;撤销证明=带宽回退旧值本断言复红)→ 宽带登记。 func _smoke_skill_pool_ev_anchor() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var bands := {"goblin": [0.82, 1.02], "bugbear": [0.97, 1.03], "ogre_chief": [1.10, 1.30]} # 地精重锚 2026-10-28(触发条件批孤注守势入池稀释,无情境口径实测 0.9148;EV 锚注 enemy.tres)· 酋长重锚(震地怒击半血解锁入池,含闸长期速率上移:实测 1.1948;EV 锚注 enemy.tres) var species := ["goblin", "bugbear", "ogre_chief"] var rng = load("res://core/rng_service.gd").new() @@ -830,6 +834,7 @@ func _smoke_skill_pool_ev_anchor() -> void: # ⑤ 死亡打断作废(摇定后、兑现前死亡 → 本拍技能作废、不动手、不进账) func _smoke_skill_pool_death_void() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var void_seed := -1 for s in range(1, 400): var rg = load("res://core/rng_service.gd").new() @@ -869,6 +874,7 @@ func _smoke_skill_pool_death_void() -> void: # ⑥ 加载校验拒绝(单表域校验 + 跨表池构成纪律) func _smoke_skill_pool_validation_reject() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var skill_table = load("res://data/schemas/skill_table.gd").new() var enemy_table = load("res://data/schemas/enemy_table.gd").new() enemy_table.rows.assign([{"enemy_id": "x", "display_name": "x", "pool": [{"skill_id": "ghost", "weight": 1}]}]) @@ -927,6 +933,7 @@ func _has_err_category(errs: Array, category: String) -> bool: # 停手轮驱动 (2,9)——零挖掘零封印 → 零池,伤害行可逐拍精确复算;种子 hunt 至少各命一粒毒爆伤害行 # 与蛛网束缚施放行;毒分量随开战掷定的攻击基线缩放(atk 区间 2–4 → rider 1–3)。 func _smoke_debuff_rider() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var venom_seed := -1 var venom_check_ok := true var venom_rows_seen := 0 @@ -997,6 +1004,7 @@ func _smoke_debuff_rider() -> void: # ---- 天赋树六键行为冒烟(V10:开局姿态窗/危险直觉限次/财富之道聚散/守侧失误补偿; # 引擎直构 + 编排授予段直注(_grant_seg._judge_seal=结算授予段封印判定单口))---- func _smoke_counter_buckets() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) print("--- 效果引擎无状态化四桶正向验收(卡② §9 V1/V6)---") # V1——adventure 桶跨战持久:同一宿主字典下两战各真实 request_dig 一次, # 断付费计数经 ctx 就地写入宿主字典并跨战累积(副本搬运态:读不到上一战值→第 2 战仍 1,此断言会红)。 @@ -1059,6 +1067,7 @@ func _smoke_counter_buckets() -> void: # V6 形态先例同源:直入真实管线缝(_judge_seal 直调同款口径)。 func _smoke_extended_rows() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) print("--- 扩展行收敛:fx_reveal 兑付/落空 ---") var RigS = load("res://core/battle_orchestrator.gd") # 局部装配别名(_smoke_counter_buckets 同款——跨函数不共享局部量) var enc_fx = {"level_index": 1, "node_depth": 0, "hero_hp": 40, "hero_atk": 8, "hero_max_hp": 40, @@ -1104,6 +1113,7 @@ func _smoke_extended_rows() -> void: # 蓄力表值 2 拍衰减后剩 1 拍仍在池)→ 逐敌读敌方输出池。判据=施放者与被他敌的池读数差。 func _smoke_enemy_buff_targets_self() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var emp_mag: int = int(_db.combat.status_effects.row_by_id("empower").magnitude) var sc_script = load("res://core/status_container.gd") var found_seed := -1 diff --git a/game/tests/unit/battle_settlement/seal_polarity_test.gd b/game/tests/unit/battle_settlement/seal_polarity_test.gd index 70178b65..71d92b31 100644 --- a/game/tests/unit/battle_settlement/seal_polarity_test.gd +++ b/game/tests/unit/battle_settlement/seal_polarity_test.gd @@ -22,7 +22,7 @@ var _db func _init() -> void: -# oracle: design/gdd/systems/排雷循环/排雷玩法.md:231(封印与极性宿主——装载组) +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:231 (封印与极性宿主——装载组) _db = ConfigDBScript.new() # 表加载失败不中止(承 G2/G3/G4 同款:表损坏的红落在具体断言上—— # 诊断在此展开,后续断言按坏表实况逐条验红;collect_only=true 下成员照常赋值可评) @@ -46,7 +46,7 @@ func _init() -> void: # ---- 末点 AP 封印轮末结算(playtest 缺陷②回归:末点 AP 花在封印必须终结轮次进入下一轮)---- func _smoke_seal_ap_exhausted() -> void: -# oracle: design/gdd/systems/排雷循环/行动经济.md:260(末点 AP 耗尽即收轮组) +# oracle: design/gdd/systems/排雷循环/行动经济.md:260 (末点 AP 耗尽即收轮组) print("--- 排雷玩法·封印动作耗尽末点 AP 回归 ---") var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(20260911) @@ -324,8 +324,8 @@ func _rows_at(rows: Array, source_class: String, cell) -> Array: func _smoke_clear_reward_chain() -> void: -# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:235(清图奖励链——清图槽对象身份组) -# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:235(清图奖励链——清图槽对象身份组) +# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:235 (清图奖励链——清图槽对象身份组) +# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:235 (清图奖励链——清图槽对象身份组) print("--- 清图奖励·双份兑付链(完美封印 / 零兑付 / 第二份被拒 / 高光记实)---") # ① 真实流完美封印:标中一面真雷封印 + 零误标 + 清全图 → grant_clear 身份(clear_blast)双份真实兑付 var rows: Array = [] @@ -354,8 +354,8 @@ func _smoke_clear_reward_chain() -> void: # 弱形式登记:正常战斗流下"授段时刻无存活敌"不可达——敌全灭当轮判定段即判胜并终止战斗,而清图批在判定段之前, # 恒有存活敌;故本组直调编排私有面构造状态,只断言"路径存在 + 行为符合契约"(构造手法见各行注释)。 func _smoke_clear_reward_zero_paths() -> void: -# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:240(无存活敌群伤记「奖励未生效」组) -# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:240(无存活敌群伤记「奖励未生效」组) +# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:240 (无存活敌群伤记「奖励未生效」组) +# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:240 (无存活敌群伤记「奖励未生效」组) # ②-a 首份零兑付判定(无存活敌)→ first_ok=false + 未生效行 var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(20260915) @@ -410,8 +410,8 @@ func _smoke_clear_reward_zero_paths() -> void: # 轮内刷新 provenance 守卫:刷新换来的图同轮清图不发清图奖励(_board_from_midround_refresh 守卫) func _smoke_refresh_provenance_guard() -> void: -# oracle: design/gdd/systems/排雷循环/排雷玩法.md:237(换图重置:旧封印印记先判定后消失组) -# oracle: design/gdd/systems/排雷循环/排雷玩法.md:237(换图重置:旧封印印记先判定后消失组) +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:237 (换图重置:旧封印印记先判定后消失组) +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:237 (换图重置:旧封印印记先判定后消失组) print("--- 轮内刷新 provenance 守卫(刷新图清图不发清图奖励)---") var rows: Array = [] var run := _run_full_clear(20260916, true, rows) @@ -438,8 +438,8 @@ func _smoke_refresh_provenance_guard() -> void: func _smoke_polarity_routing() -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:366(极性路由:正向只兑正向、负向只兑负向组) -# oracle: design/gdd/systems/战斗循环/战斗结算.md:366(极性路由:正向只兑正向、负向只兑负向组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:366 (极性路由:正向只兑正向、负向只兑负向组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:366 (极性路由:正向只兑正向、负向只兑负向组) print("--- 极性路由(挖安全格正向 / 挖危险格负向 / 标中正向 / 标空负向)---") # 战斗随机值面随全局序漂移——构造种子按行为面扫描(谓词见 _polarity_probe_accepts) var probe := {} @@ -577,8 +577,8 @@ func _smoke_polarity_routing() -> void: # 场景 B(②):标危险格 → 直接挖开 → 收轮。 # 场景 C(①③):标安全格 + 标危险格 → 不挖收轮 → 标空/标中判定照常。 func _smoke_seal_irreversible_quadrants() -> void: -# oracle: design/gdd/systems/排雷循环/排雷玩法.md:231(封印不可逆四情况组) -# oracle: design/gdd/systems/排雷循环/排雷玩法.md:231(封印不可逆四情况组) +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:231 (封印不可逆四情况组) +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:231 (封印不可逆四情况组) print("--- 封印不可逆四情况(禁撤封印 + 挖封印格兑付改判)---") # 场景 A:安全格直挖(情况④)+ seal_pull/重复封印拒绝面 var rng_a = load("res://core/rng_service.gd").new() @@ -687,8 +687,8 @@ func _smoke_seal_irreversible_quadrants() -> void: # 负向字典逐型直验(类型化兑付行协议):找真实板上各型非封锁格,直调 grant_routed 负向路由(att 归因束形态), # 断言每型的兑付形态(enrage/off_guard/sapped 效果行、heal 直伤行、blast 警觉行、action 行动点排队)。 func _smoke_negative_dictionary() -> void: -# oracle: design/gdd/systems/排雷循环/行动经济.md:256(下轮行动点修正排队与兑现组) -# oracle: design/gdd/systems/排雷循环/行动经济.md:256(下轮行动点修正排队与兑现组) +# oracle: design/gdd/systems/排雷循环/行动经济.md:256 (下轮行动点修正排队与兑现组) +# oracle: design/gdd/systems/排雷循环/行动经济.md:256 (下轮行动点修正排队与兑现组) print("--- 负向字典逐型直验(sapped 在位 / heal 直伤 / blast 警觉 / action 行动点)---") # 数据面:sapped 行在位(状态表七行 + effect_pool_map 映射在位) var sapped: Dictionary = _db.combat.status_effects.row_by_id("sapped") @@ -782,8 +782,8 @@ func _smoke_negative_dictionary() -> void: # 资源面断言:chain/dig 事件恒携带 resource=true(危险格同权);initial 恒 false(封锁格); # 封锁格查询 = null、危险格未开恒可查。 func _smoke_resource_surface() -> void: -# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:235(资源面只读查询组) -# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:235(资源面只读查询组) +# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:235 (资源面只读查询组) +# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:235 (资源面只读查询组) print("--- 格面资源资格面(危险格携带 / 封锁格无资源)---") var run1 = _run_battle(1, 0) var run2 = _run_battle(2, 0) diff --git a/game/tests/unit/battle_settlement/settlement_wiring_snapshot_test.gd b/game/tests/unit/battle_settlement/settlement_wiring_snapshot_test.gd index 934c1aaf..c3394f27 100644 --- a/game/tests/unit/battle_settlement/settlement_wiring_snapshot_test.gd +++ b/game/tests/unit/battle_settlement/settlement_wiring_snapshot_test.gd @@ -419,7 +419,7 @@ var _db func _init() -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:362(结算接线同种子逐项 golden 对拍组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:362 (结算接线同种子逐项 golden 对拍组) _db = ConfigDBScript.new() var load_ok: bool = _db.load_tables("res://data/tables", true) Kit.check("前置:表加载零 error", load_ok and _db.diagnostics_count("error") == 0) diff --git a/game/tests/unit/battle_settlement/skill_unlock_test.gd b/game/tests/unit/battle_settlement/skill_unlock_test.gd index 53005034..c504f9bd 100644 --- a/game/tests/unit/battle_settlement/skill_unlock_test.gd +++ b/game/tests/unit/battle_settlement/skill_unlock_test.gd @@ -26,6 +26,7 @@ func _init() -> void: # 门谓词:卓尔 (2,9) hp 130(×mult 1.0)→ venom_curb unlock 50 → 阈值 round(130×0.5)=65 func _boss(db, L: int, D: int, kind := "boss"): +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var ec = UnitContainerScript.new(db) var ok: bool = ec.spawn({"level_index": L, "node_depth": D, "hero_hp": int(db.combat.hero.max_hp), "row_kind": kind}) Kit.check("前置:spawn (%d,%d) 受理" % [L, D], ok) @@ -44,7 +45,7 @@ func _has_sid(arr: Array, sid: String) -> bool: func _test_gate_predicate(db) -> void: -# oracle: design/gdd/systems/战斗循环/敌人系统.md:143(门谓词:条件不满足不进可摇集合组) +# oracle: design/gdd/systems/战斗循环/敌人系统.md:143 (门谓词:条件不满足不进可摇集合组) var ec = _boss(db, 2, 9) var u: Dictionary = _boss_u(ec) var mhp: int = int(u.max_hp) @@ -73,7 +74,7 @@ func _test_gate_predicate(db) -> void: # 闩不可逆:解锁后治疗抬回满血 → 复查零新解锁、可摇集合不回退 func _test_latch_irreversible(db) -> void: -# oracle: design/gdd/systems/战斗循环/敌人系统.md:143(闩型条件首次为真整场保持组) +# oracle: design/gdd/systems/战斗循环/敌人系统.md:143 (闩型条件首次为真整场保持组) var ec = _boss(db, 2, 9) var u: Dictionary = _boss_u(ec) ec.apply_damage(u, int(u.max_hp) / 2) # → 半血触发 @@ -85,7 +86,7 @@ func _test_latch_irreversible(db) -> void: # 普通行无字段逐位零扰动:地精 (1,0) 池快照零 unlock 键、过滤恒空转、可摇=全池 func _test_plain_rows_zero_drift(db) -> void: -# oracle: design/gdd/systems/战斗循环/敌人系统.md:301(普攻倍率 1 特例——零漂移组) +# oracle: design/gdd/systems/战斗循环/敌人系统.md:301 (普攻倍率 1 特例——零漂移组) var ec = load("res://core/unit_container.gd").new(db) Kit.check("零扰动前置:巨蜘蛛首遇带 spawn(池三行全无 trigger——快照键策略钉死载体)", ec.spawn({"level_index": 2, "node_depth": 1, "hero_hp": int(db.combat.hero.max_hp)})) var u: Dictionary = ec.all_enemies()[0] diff --git a/game/tests/unit/battle_settlement/trigger_cond_test.gd b/game/tests/unit/battle_settlement/trigger_cond_test.gd index fd6347ae..1852c966 100644 --- a/game/tests/unit/battle_settlement/trigger_cond_test.gd +++ b/game/tests/unit/battle_settlement/trigger_cond_test.gd @@ -9,7 +9,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: -# oracle: design/gdd/systems/战斗循环/敌人系统.md:143(触发条件机制 V1–V10 组) +# oracle: design/gdd/systems/战斗循环/敌人系统.md:143 (触发条件机制 V1–V10 组) var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): print("[trigger_cond_test] FAIL — 数值表加载失败") diff --git a/game/tests/unit/battle_settlement/variant_placement_test.gd b/game/tests/unit/battle_settlement/variant_placement_test.gd index b8963d6b..e900d82a 100644 --- a/game/tests/unit/battle_settlement/variant_placement_test.gd +++ b/game/tests/unit/battle_settlement/variant_placement_test.gd @@ -54,7 +54,7 @@ class _CountVariantRng extends RngServiceCore: # 本段经 begin_battle 走完整初始化序后断言:门控一致性 / 布置域 / 数量公式 / 连通片上限 / 确定性。 func _smoke_variant_placement(L: int) -> void: -# oracle: design/gdd/systems/排雷循环/地形变异.md:63(战内布置段门控组) +# oracle: design/gdd/systems/排雷循环/地形变异.md:63 (战内布置段门控组) print("--- 地形变异 布置段(L%d)---" % L) var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(42) @@ -148,7 +148,7 @@ func _variant_dump(b) -> String: func _smoke_global_variant() -> void: -# oracle: design/gdd/systems/排雷循环/地形变异.md:74(全局替换制与回落组) +# oracle: design/gdd/systems/排雷循环/地形变异.md:74 (全局替换制与回落组) print("--- 全局作用域变异(门控三维 + 全局池空兜底回落 + 资源面偏斜)---") # ① 跨字段互锁负样本(resource_face ⟺ scope=global 三条 + effect_value 新域 [0,50]) var vt = load("res://data/schemas/variation_table.gd").new() @@ -343,7 +343,7 @@ func _errs_has_cross_field(errs: Array) -> bool: # 全称不可断)。可达判据=①静态(布置面零字面量下界)+②同种子改值产物互异(真实入口=begin_battle 布置段)。 func _test_pack_min_from_table() -> void: -# oracle: design/gdd/systems/排雷循环/地形变异.md:63(连通片格数 [pack_min,pack_max] 读表组) +# oracle: design/gdd/systems/排雷循环/地形变异.md:63 (连通片格数 [pack_min,pack_max] 读表组) # ① 静态:布置面零字面量下界(randi_range(2, 退役——下界读 pack_min 表头单点) var src := FileAccess.get_file_as_string("res://core/board_installer.gd") Kit.check("布置面零字面量下界(randi_range(2, 退役、下界读表单点在位)〔架构整改 V10·静态〕", diff --git a/game/tests/unit/contracts/source_guard_test.gd b/game/tests/unit/contracts/source_guard_test.gd index 86822e4f..4a386b4c 100644 --- a/game/tests/unit/contracts/source_guard_test.gd +++ b/game/tests/unit/contracts/source_guard_test.gd @@ -21,7 +21,7 @@ func _init() -> void: # ---- 类型闸断言(V7——project.godot warning 配置在位〔源码断言〕+审计器脚本在位; # 审计器归零判定走 static_scan S9 闸机,此处兜配置面)---- func _smoke_type_gate() -> void: -# oracle: design/engineering/code-conventions.md:41(封装边界——类型闸源码扫描组) +# oracle: design/engineering/code-conventions.md:41 (封装边界——类型闸源码扫描组) var pj: String = FileAccess.get_file_as_string("res://project.godot") Kit.check("V7 类型闸 warning 配置在位(untyped_declaration=1 显形)〔迭代27 T5〕", pj.contains("gdscript/warnings/untyped_declaration=1")) @@ -32,7 +32,7 @@ func _smoke_type_gate() -> void: # ---- 卫生件 grep 闸(V8——死代码/字符串 Callable/影子账残留零命中;源码扫描面)---- func _smoke_hygiene_gates() -> void: -# oracle: design/engineering/code-conventions.md:54(模态覆盖层层级与登记纪律——卫生闸组) +# oracle: design/engineering/code-conventions.md:54 (模态覆盖层层级与登记纪律——卫生闸组) var callables := 0 for d in ["res://core", "res://presentation", "res://data"]: var dir := DirAccess.open(d) diff --git a/game/tests/unit/contracts/system_contracts_test.gd b/game/tests/unit/contracts/system_contracts_test.gd index a5d3cc0b..2a499efc 100644 --- a/game/tests/unit/contracts/system_contracts_test.gd +++ b/game/tests/unit/contracts/system_contracts_test.gd @@ -18,6 +18,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") # T6 收口:_check/汇 func _init() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var db = ConfigDBScript.new() var load_ok: bool = db.load_tables("res://data/tables", true) Kit.check("前置:表加载零 error", load_ok and db.diagnostics_count("error") == 0) @@ -40,8 +41,8 @@ func _init() -> void: # ---- B1 兑付配方词表:五配方/三目标规则/双结账政策——常量非空且互异(封闭枚举负空间) ---- func _test_damage_controller_vocabularies() -> void: -# oracle: design/engineering/architecture/architecture.md:89(事件/事实/效果类型/算子四词表封闭——契约词表组) -# oracle: design/engineering/architecture/architecture.md:89(事件/事实/效果类型/算子四词表封闭——契约词表组) +# oracle: design/engineering/architecture/architecture.md:89 (事件/事实/效果类型/算子四词表封闭——契约词表组) +# oracle: design/engineering/architecture/architecture.md:89 (事件/事实/效果类型/算子四词表封闭——契约词表组) var kinds: Array = [ DamageControllerScript.KIND_HERO_ATTACK, DamageControllerScript.KIND_ENEMY_SKILL, DamageControllerScript.KIND_BOARD_TYPED, DamageControllerScript.KIND_BOARD_BLAST, @@ -71,8 +72,8 @@ func _test_damage_controller_vocabularies() -> void: # ---- D2↔B1:掷点用途标签 ∈ RngService 封闭词表(EC12——跨系统字面量契约的成员性断言) ---- func _test_rng_tag_closure(db) -> void: -# oracle: design/engineering/architecture/architecture.md:90(流 scope 封闭词表组) -# oracle: design/engineering/architecture/architecture.md:90(流 scope 封闭词表组) +# oracle: design/engineering/architecture/architecture.md:90 (流 scope 封闭词表组) +# oracle: design/engineering/architecture/architecture.md:90 (流 scope 封闭词表组) var stream_label: String = String(db.combat.settlement.damage_roll.armor_roll_stream) Kit.check("settlement.armor_roll_stream ∈ RngService 封闭标签词表(EC12)", RngServiceScript.PURPOSE_TAGS.has(stream_label)) @@ -86,8 +87,8 @@ func _test_rng_tag_closure(db) -> void: # ---- B1→D1 行协议:单据九栏缺省齐备 + 协议公共键形态 ---- func _test_ticket_nine_columns() -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:362(单据九列协议组) -# oracle: design/gdd/systems/战斗循环/战斗结算.md:362(单据九列协议组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:362 (单据九列协议组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:362 (单据九列协议组) var ctrl = _bare_controller() var t: Dictionary = ctrl.open_ticket(DamageControllerScript.KIND_BOARD_FLAT_HERO, "mine_hit", "契约探针", {"channel": "棋盘兑付", "base_value": 1, "target_rule": DamageControllerScript.TARGET_HERO, "ri": 0}) @@ -117,8 +118,8 @@ func _bare_controller(): # ---- B4→B3:增益授予布尔受理口径(受理/拒绝二元面 + 投影一致性) ---- func _test_status_boolean_acceptance(db) -> void: -# oracle: design/gdd/systems/战斗循环/增益状态.md:250(受理布尔面组) -# oracle: design/gdd/systems/战斗循环/增益状态.md:250(受理布尔面组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:250 (受理布尔面组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:250 (受理布尔面组) var effects = StatusContainerScript.new(db) # EC1 域闭:notify_battle_start 前授予 = false(受理面封闭) var any_row: Dictionary = {} @@ -145,8 +146,8 @@ func _test_status_boolean_acceptance(db) -> void: # 个体键直传字面量("e1"/"e2"/"e3"——拼写约定单点在 StatusContainer.owner_key_for,测试面模拟授予路径逐只授) func _test_status_individual_isolation(db) -> void: -# oracle: design/gdd/systems/战斗循环/增益状态.md:251(按个体归属组) -# oracle: design/gdd/systems/战斗循环/增益状态.md:251(按个体归属组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:251 (按个体归属组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:251 (按个体归属组) var effects = StatusContainerScript.new(db) effects.notify_battle_start() var src := {"source_class": "seal_hit", "origin_cell": Vector2i(-1, -1), "round_index": 0} @@ -168,8 +169,8 @@ func _test_status_individual_isolation(db) -> void: func _test_status_grant_all_per_unit(db) -> void: -# oracle: design/gdd/systems/战斗循环/增益状态.md:252(授予即生效组) -# oracle: design/gdd/systems/战斗循环/增益状态.md:252(授予即生效组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:252 (授予即生效组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:252 (授予即生效组) var effects = StatusContainerScript.new(db) effects.notify_battle_start() var src := {"source_class": "mine_hit", "origin_cell": Vector2i(-1, -1), "round_index": 0} @@ -196,8 +197,8 @@ func _test_status_grant_all_per_unit(db) -> void: func _test_status_death_clears(db) -> void: -# oracle: design/gdd/systems/战斗循环/增益状态.md:250(战斗结束清空组) -# oracle: design/gdd/systems/战斗循环/增益状态.md:250(战斗结束清空组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:250 (战斗结束清空组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:250 (战斗结束清空组) var effects = StatusContainerScript.new(db) effects.notify_battle_start() var src := {"source_class": "seal_hit", "origin_cell": Vector2i(-1, -1), "round_index": 0} @@ -211,8 +212,8 @@ func _test_status_death_clears(db) -> void: func _test_status_merge_per_unit(db) -> void: -# oracle: design/gdd/systems/战斗循环/增益状态.md:253(只登记不去重组) -# oracle: design/gdd/systems/战斗循环/增益状态.md:253(只登记不去重组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:253 (只登记不去重组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:253 (只登记不去重组) var effects = StatusContainerScript.new(db) effects.notify_battle_start() var src := {"source_class": "enemy_action", "origin_cell": Vector2i(-1, -1), "round_index": 0} @@ -235,8 +236,8 @@ func _test_status_merge_per_unit(db) -> void: # ---- B4 结算链契约(断言补齐批——①增益状态结算链):衰减逐值/战斗结束全清/满层拒绝/独立并存/首授快照 ---- func _test_status_decay_and_clear(db) -> void: -# oracle: design/gdd/systems/战斗循环/增益状态.md:21(先兑付后衰减组) -# oracle: design/gdd/systems/战斗循环/增益状态.md:21(先兑付后衰减组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:21 (先兑付后衰减组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:21 (先兑付后衰减组) var effects = StatusContainerScript.new(db) effects.notify_battle_start() var src := {"source_class": "seal_hit", "origin_cell": Vector2i(-1, -1), "round_index": 0} @@ -257,8 +258,8 @@ func _test_status_decay_and_clear(db) -> void: func _test_status_stack_full_reject(db) -> void: -# oracle: design/gdd/systems/战斗循环/增益状态.md:255(满层拒绝原子且留痕组) -# oracle: design/gdd/systems/战斗循环/增益状态.md:255(满层拒绝原子且留痕组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:255 (满层拒绝原子且留痕组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:255 (满层拒绝原子且留痕组) var effects = StatusContainerScript.new(db) effects.notify_battle_start() var src := {"source_class": "seal_hit", "origin_cell": Vector2i(-1, -1), "round_index": 0} @@ -276,8 +277,8 @@ func _test_status_stack_full_reject(db) -> void: func _test_status_independent_branch(db) -> void: -# oracle: design/gdd/systems/战斗循环/增益状态.md:257(合成不设上下限组) -# oracle: design/gdd/systems/战斗循环/增益状态.md:257(合成不设上下限组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:257 (合成不设上下限组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:257 (合成不设上下限组) var effects = StatusContainerScript.new(db) effects.notify_battle_start() var probe := { @@ -302,8 +303,8 @@ func _test_status_independent_branch(db) -> void: func _test_status_snapshot_first_grant(db) -> void: -# oracle: design/gdd/systems/战斗循环/增益状态.md:258(快照抗重载组) -# oracle: design/gdd/systems/战斗循环/增益状态.md:258(快照抗重载组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:258 (快照抗重载组) +# oracle: design/gdd/systems/战斗循环/增益状态.md:258 (快照抗重载组) var effects = StatusContainerScript.new(db) effects.notify_battle_start() var src_first := {"source_class": "seal_hit", "origin_cell": Vector2i(3, 4), "round_index": 1} diff --git a/game/tests/unit/core/adventure_feats_test.gd b/game/tests/unit/core/adventure_feats_test.gd index 623a42e7..ee0eb005 100644 --- a/game/tests/unit/core/adventure_feats_test.gd +++ b/game/tests/unit/core/adventure_feats_test.gd @@ -59,7 +59,7 @@ func _hits_kind(hits: Array, kind: String) -> Array: # ② 冒险结构 API 闸(状态机受理面——重复开始拒绝 / 入口停点 / 放弃两态) func _smoke_adventure_api() -> void: -# oracle: design/gdd/systems/冒险循环/冒险结构.md:283(冒险 API 组:开始受理/序列/回调) +# oracle: design/gdd/systems/冒险循环/冒险结构.md:283 (冒险 API 组:开始受理/序列/回调) print("--- 冒险结构 API 闸(重复开始拒绝 · 入口停点 · 放弃两态受理)---") var adr = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(42)) adr.set_hero_override(900, 400) # 首战速胜档(放弃的非战斗受理要走到选路态) @@ -122,7 +122,7 @@ func _api_mark_node(_node: Dictionary, _info: Dictionary, seq: Array) -> void: # ③ 冒险验收断言(映射 冒险结构.md 验收标准——表覆盖/满配冒险成功/种子复现/大奖励/败北线/ # 重复拒绝/GP 跨关延续/加算区同账/恢复数学/放弃) func _smoke_adventure() -> void: -# oracle: design/gdd/systems/冒险循环/冒险结构.md:284(冒险生命周期组:推进/末关/倒下/重开/生命账) +# oracle: design/gdd/systems/冒险循环/冒险结构.md:284 (冒险生命周期组:推进/末关/倒下/重开/生命账) print("--- 冒险结构验收(三关序列 · 大奖励 · 摘要五件事 · 账本封闭)---") var autoplay = load("res://sim/level_autoplay.gd") # ① 表与覆盖义务(序列关数 = 行集关数;节点源 = 参数档在固定种子下的生成图, @@ -463,7 +463,7 @@ func _smoke_adventure() -> void: # ---- 专长冒烟(feats 四级 · 案D 池接线 · V3 订阅面逐件三列)---- func _smoke_feats() -> void: -# oracle: design/gdd/systems/冒险循环/奇物.md:465(奇物授予与凭证保底组) +# oracle: design/gdd/systems/冒险循环/奇物.md:465 (奇物授予与凭证保底组) print("--- 专长重设计实装(feat_table 四级 · 专长带池接线 · 订阅面逐件)---") # ① 现行表牌库构成:37 件全量入池——102 数值令牌+37 relic 令牌(四级 rarity 直映射) Kit.check("feat_table 已加载(37 件=基础 27+迁入 2+完美保险 1+迭代 46 换图系七件——换代)", _db.crossrun.feats != null and (_db.crossrun.feats.rows as Array).size() == 37) diff --git a/game/tests/unit/core/auto_player_deduce_test.gd b/game/tests/unit/core/auto_player_deduce_test.gd index f9dfcb0b..47d1a6bf 100644 --- a/game/tests/unit/core/auto_player_deduce_test.gd +++ b/game/tests/unit/core/auto_player_deduce_test.gd @@ -16,7 +16,7 @@ func _init() -> void: func _smoke_zero_chain_rule() -> void: -# oracle: design/gdd/systems/排雷循环/排雷玩法.md:230(0 格连锁传播闭包——模拟玩家算子组) +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:230 (0 格连锁传播闭包——模拟玩家算子组) var db = load("res://core/config_db.gd").new() var load_ok: bool = db.load_tables("res://data/tables", true) and db.diagnostics_count("error") == 0 Kit.check("前置:表加载零 error", load_ok) diff --git a/game/tests/unit/core/battle_driver_drive_test.gd b/game/tests/unit/core/battle_driver_drive_test.gd index 706aa28e..7df68bd3 100644 --- a/game/tests/unit/core/battle_driver_drive_test.gd +++ b/game/tests/unit/core/battle_driver_drive_test.gd @@ -55,7 +55,7 @@ func _init() -> void: # ① 缺省两参(真编排器):同种子两跑整轮驱动逐位(确定性自证——动作序列快照经 cell_revealed 事件流) func _smoke_drive_round_contract() -> void: -# oracle: design/engineering/architecture/architecture.md:144(效果端口件:收事件交结算取回命中批——驱动循环契约组) +# oracle: design/engineering/architecture/architecture.md:144 (效果端口件:收事件交结算取回命中批——驱动循环契约组) var db = load("res://core/config_db.gd").new() var load_ok: bool = db.load_tables("res://data/tables", true) and db.diagnostics_count("error") == 0 Kit.check("前置:表加载零 error", load_ok) @@ -81,7 +81,7 @@ func _smoke_drive_round_contract() -> void: # ② provider 形态:策略回调产出 dig/seal_place/refresh 各一——提交与日志回调四元组在案 func _provider_shapes() -> void: -# oracle: design/engineering/architecture/architecture.md:144(端口应答束形状组) +# oracle: design/engineering/architecture/architecture.md:144 (端口应答束形状组) var st := _StubSettlement.new() var script := [ {"kind": "dig", "cell": Vector2i(1, 1)}, {"kind": "seal", "cell": Vector2i(2, 2)}, {"kind": "refresh"}, {"kind": "stop"} ] var logs: Array = [] @@ -102,7 +102,7 @@ func _provider_shapes() -> void: # ③ max_rejects:策略恒返被拒动作——第 3 拒后停手出环(循环次数=3) func _max_rejects() -> void: -# oracle: design/engineering/architecture/architecture.md:144(拒绝通道组) +# oracle: design/engineering/architecture/architecture.md:144 (拒绝通道组) var st := _StubSettlement.new() st.minesweeper.accept = false st.minesweeper.reject_cells = {Vector2i(9, 9): true} @@ -122,7 +122,7 @@ func _max_rejects() -> void: # ④ 合步 next:move 后相位变更即断弃 dig(桩 on_submit 钩子把 phase 推离 Active) func _combined_step_next() -> void: -# oracle: design/engineering/architecture/architecture.md:144(合并步进组) +# oracle: design/engineering/architecture/architecture.md:144 (合并步进组) var st := _StubSettlement.new() st.minesweeper.on_submit = func(action: String) -> void: if action == "move": diff --git a/game/tests/unit/core/board_gen_reward_test.gd b/game/tests/unit/core/board_gen_reward_test.gd index 3f465f05..8e734dab 100644 --- a/game/tests/unit/core/board_gen_reward_test.gd +++ b/game/tests/unit/core/board_gen_reward_test.gd @@ -52,7 +52,7 @@ func _mk_stream(stream_name: String, scope: int) -> RandomNumberGenerator: # 公式 N×cell ≤ 可用高−12 必须计入 (N−1)×2px 网格间距,否则网格实高溢出被 clip_contents 裁掉; # 现公式 = 计入间距 + 垂直预留 24px〔上 12/下 12——底部不贴 D 区边框〕)---- func _smoke_layout_cell_formula() -> void: -# oracle: design/gdd/systems/排雷循环/棋盘生成.md:75(出生区边长表单点——格边长公式组) +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:75 (出生区边长表单点——格边长公式组) print("--- 棋盘布局格边长公式(底部预留回归·四档板型)---") var board_generator = load("res://core/board_generator.gd").new() var board_view = load("res://presentation/views/board_view.gd").new() @@ -82,7 +82,7 @@ func _smoke_layout_cell_formula() -> void: # ---- 地图战斗资源·身份面单元冒烟(格面资源:roll 恰一次 / 雷安同池 / 幂等 / 清图批尾)---- func _smoke_reward_identity_unit() -> void: -# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:233(格面资源身份——三分出口与资源身份组) +# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:233 (格面资源身份——三分出口与资源身份组) print("--- 地图战斗资源·格面资源身份面 ---") var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(20260911) @@ -144,7 +144,7 @@ class _BoardRowStub: func _smoke_board_generator() -> void: -# oracle: design/gdd/systems/排雷循环/棋盘生成.md:221(确定性复现+布雷纪律组) +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:221 (确定性复现+布雷纪律组) print("--- 棋盘生成 ---") var board_generator = load("res://core/board_generator.gd").new() for L in [1, 2]: @@ -239,7 +239,7 @@ func _board_dump(b) -> String: # ---- 地图战斗资源·伤害量值区间冒烟(roll 域内 + 中点锚 + 变异实际流动 + 定值行不受扰)---- func _smoke_power_interval() -> void: -# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:233(资源量值区间——伤害量值区间组) +# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:233 (资源量值区间——伤害量值区间组) print("--- 地图战斗资源·伤害量值区间(上阶/下阶随机)---") # ① 表侧静态锚(配置推导——改表不断锚):凡带 power_min/power_max 的行 = 区间行, # 校验配对齐全(lo ≤ hi)+ power = floor 中点(行动经济 条款①期望当量锚);其余行必须零区间字段。 diff --git a/game/tests/unit/core/board_generator_test.gd b/game/tests/unit/core/board_generator_test.gd index 182794f0..698b5d52 100644 --- a/game/tests/unit/core/board_generator_test.gd +++ b/game/tests/unit/core/board_generator_test.gd @@ -40,7 +40,7 @@ func _generate(L: int, D: int, seed0: int) -> BoardData: func _test_generate_shape_and_mines() -> void: -# oracle: design/gdd/systems/排雷循环/棋盘生成.md:224(布雷纪律组) +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:224 (布雷纪律组) var b := _generate(1, 0, 71000) if b == null: Kit.check("生成返回棋盘", false) @@ -61,7 +61,7 @@ func _test_generate_shape_and_mines() -> void: # 目标雷数公式单点(d14):同参同值对拍原式 + 真实产图指标读数同源 func _test_target_mine_count_single_source() -> void: -# oracle: design/gdd/systems/排雷循环/棋盘生成.md:224(雷数单源组) +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:224 (雷数单源组) var bad := 0 var checked := 0 for L in [1, 2, 3]: @@ -92,7 +92,7 @@ func _test_target_mine_count_single_source() -> void: func _test_digits_equal_neighbor_mine_count() -> void: -# oracle: design/gdd/systems/排雷循环/棋盘生成.md:223(数字恒真组) +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:223 (数字恒真组) var b := _generate(1, 1, 72000) if b == null: Kit.check("生成返回棋盘(数字段)", false) @@ -113,7 +113,7 @@ func _test_digits_equal_neighbor_mine_count() -> void: func _test_same_seed_bit_identical() -> void: -# oracle: design/gdd/systems/排雷循环/棋盘生成.md:221(同种子逐位复现组) +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:221 (同种子逐位复现组) var a := _generate(2, 0, 73000) var b := _generate(2, 0, 73000) if a == null or b == null: @@ -124,7 +124,7 @@ func _test_same_seed_bit_identical() -> void: func _test_clearable_and_inferability_selfconsistent() -> void: -# oracle: design/gdd/systems/排雷循环/棋盘生成.md:226(可清图与及格线自洽组) +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:226 (可清图与及格线自洽组) var b := _generate(1, 0, 74000) if b == null: Kit.check("生成返回棋盘(可推理段)", false) @@ -140,7 +140,7 @@ func _test_clearable_and_inferability_selfconsistent() -> void: # ---- V8 出生区边长表单点(架构整改——spawn_edge 表头驱动布雷域基/几何/护栏全导出)---- func _test_spawn_edge_from_table() -> void: -# oracle: design/gdd/systems/排雷循环/棋盘生成.md:75(出生区边长读表组) +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:75 (出生区边长读表组) # ① 纯函数对拍:edge=5 夹具 → target = round(d×(W×H−25))(25 格布雷域基可观测) var p5 := {"w": 12, "h": 12, "density": 0.15, "spawn_edge": 5} Kit.check("V8 纯函数:edge=5 布雷域基 25 格(target=round(d×(144−25)))〔架构整改 V8〕", diff --git a/game/tests/unit/core/breakpoint_resume_test.gd b/game/tests/unit/core/breakpoint_resume_test.gd index c68200b9..24b28c4a 100644 --- a/game/tests/unit/core/breakpoint_resume_test.gd +++ b/game/tests/unit/core/breakpoint_resume_test.gd @@ -15,7 +15,7 @@ var _bp_path := "user://test_breakpoint_resume.json" func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:180(断点域契约:七字段往返/续玩确定性/幂等/三结局清除组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:180 (断点域契约:七字段往返/续玩确定性/幂等/三结局清除组) var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): print("[breakpoint_resume_test] FAIL — 数值表加载失败") diff --git a/game/tests/unit/core/config_db_cross_validator_test.gd b/game/tests/unit/core/config_db_cross_validator_test.gd index 0b82f07d..8cb7ee18 100644 --- a/game/tests/unit/core/config_db_cross_validator_test.gd +++ b/game/tests/unit/core/config_db_cross_validator_test.gd @@ -13,7 +13,7 @@ const StatusTableScript := preload("res://data/schemas/status_effect_table.gd") func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:195(跨表校验宿主——装载组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:195 (跨表校验宿主——装载组) _test_all_links_valid() _test_dangling_skill_id() _test_cast_side_mismatch() @@ -47,7 +47,7 @@ func _cats(errs: Array) -> Array[String]: # ---- 正向:技能池全对齿(普攻恰一行、buff 挂敌方侧)应零错,防校验误伤 ---- func _test_all_links_valid() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:195(悬空引用类别:跨表链接全有效组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:195 (悬空引用类别:跨表链接全有效组) var skills := _skill([ {"skill_id": "attack", "type": "basic"}, {"skill_id": "raise_morale", "type": "buff", "buff_ref": "st_strong"}, @@ -63,7 +63,7 @@ func _test_all_links_valid() -> void: # ---- 负向:技能池引用表里不存在的 skill_id 必须报 ---- func _test_dangling_skill_id() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:195(悬空引用类别:skill_id 悬空组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:195 (悬空引用类别:skill_id 悬空组) var skills := _skill([{"skill_id": "attack", "type": "basic"}]) var enemies := _enemy([ {"level_index": 1, "row_kind": "battle", "depth_band": 0, "enemy_id": "goblin", "pool": [ @@ -76,7 +76,7 @@ func _test_dangling_skill_id() -> void: # ---- 负向:buff 挂到主角侧状态(side 反向)必须报 ---- func _test_cast_side_mismatch() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:195(side 反向校验组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:195 (side 反向校验组) var skills := _skill([{"skill_id": "raise_morale", "type": "buff", "buff_ref": "st_hero_side"}]) var enemies := _enemy([ {"level_index": 1, "row_kind": "battle", "depth_band": 0, "enemy_id": "goblin", "pool": [ diff --git a/game/tests/unit/core/config_db_resolver_test.gd b/game/tests/unit/core/config_db_resolver_test.gd index 40626662..9e5e4c53 100644 --- a/game/tests/unit/core/config_db_resolver_test.gd +++ b/game/tests/unit/core/config_db_resolver_test.gd @@ -12,7 +12,7 @@ var _resolver: ConfigDbResolver func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:202(解析器宿主——装载组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:202 (解析器宿主——装载组) _resolver = ResolverScript.new( func(level, category, message) -> void: # 诊断通道签名按调用实参收(首参为表 id 字符串) _diags.append("%s/%s/%s" % [str(level), str(category), str(message)]), @@ -55,7 +55,7 @@ func _difficulty_table(): func _test_band_hit() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:202(精确命中零警告组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:202 (精确命中零警告组) var hit: Array = _resolver.resolve_enemy_rowset(1, 4, "battle") Kit.check("带命中取偏难一侧:请求深度 4 命中带 5(逐字不回带 0)〔fv1〕", hit.size() == 1 and String((hit[0] as Dictionary).get("enemy_id", "")) == "giant_spider") @@ -65,7 +65,7 @@ func _test_band_hit() -> void: func _test_rowset_order_preserved() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:202(行集寻址与行序保序组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:202 (行集寻址与行序保序组) var rows: Array = _resolver.resolve_enemy_rowset(1, 0, "battle") var ids: Array[String] = [] for r in rows: @@ -75,7 +75,7 @@ func _test_rowset_order_preserved() -> void: func _test_top_band_clamp() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:202(超最大行走封顶取最大行组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:202 (超最大行走封顶取最大行组) _diags.clear() var rows: Array = _resolver.resolve_enemy_rowset(1, 99, "battle") Kit.check("越顶带 clamp 取顶带行集(battle 顶带 5)〔fv3〕", @@ -91,7 +91,7 @@ func _test_top_band_clamp() -> void: func _test_row_kind_routing() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:202(行类别路由组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:202 (行类别路由组) var battle_rows: Array = _resolver.resolve_enemy_rowset(1, 0, "battle") var boss_rows: Array = _resolver.resolve_enemy_rowset(1, 0, "boss") Kit.check("行类路由:同请求深度 battle 与 boss 命中不同键域〔fv4〕", @@ -100,7 +100,7 @@ func _test_row_kind_routing() -> void: func _test_request_oob() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:203(越域致命中止组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:203 (越域致命中止组) _diags.clear() _resolver.resolve_enemy_rowset(0, 0, "battle") Kit.check("关卡序号 <1 → fatal request_oob〔fv5〕", _has_fatal_oob()) @@ -120,7 +120,7 @@ func _has_fatal_oob() -> bool: func _test_difficulty_clamp() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:202(难度 clamp 组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:202 (难度 clamp 组) var m: Dictionary = _resolver.resolve_difficulty_modifiers(1, 0) Kit.check("难度乘数越域被 clamp:hp 99 → 上限 10", absf(float(m.get("hp_mult", 0.0)) - 10.0) < 0.001) Kit.check("难度乘数越域被 clamp:atk 0.01 → 下限 0.1", absf(float(m.get("atk_mult", 0.0)) - 0.1) < 0.001) diff --git a/game/tests/unit/core/curio_refresh_paid_test.gd b/game/tests/unit/core/curio_refresh_paid_test.gd index 94e2a06f..6be57be7 100644 --- a/game/tests/unit/core/curio_refresh_paid_test.gd +++ b/game/tests/unit/core/curio_refresh_paid_test.gd @@ -8,7 +8,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: -# oracle: design/engineering/architecture/architecture.md:107(CurioDeck:三选一/商店共享池、抽签、cap 库存——刷新付费组) +# oracle: design/engineering/architecture/architecture.md:107 (CurioDeck:三选一/商店共享池、抽签、cap 库存——刷新付费组) var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): print("[curio_refresh_paid_test] FAIL — 数值表加载失败") diff --git a/game/tests/unit/core/effect_words_t1_test.gd b/game/tests/unit/core/effect_words_t1_test.gd index 265ff860..c9902171 100644 --- a/game/tests/unit/core/effect_words_t1_test.gd +++ b/game/tests/unit/core/effect_words_t1_test.gd @@ -11,7 +11,7 @@ const EffectEngineScript = preload("res://core/effect_engine.gd") func _init() -> void: -# oracle: design/engineering/architecture/architecture.md:89(效果词表封闭——扩签封闭性组) +# oracle: design/engineering/architecture/architecture.md:89 (效果词表封闭——扩签封闭性组) # ① 词表在册断言(扩签面:2 事件+8 事实+7 效果类型+1 算子) Kit.check_quiet(EffectEngineScript.EVENTS.has("dig_stop") and EffectEngineScript.EVENTS.has("battle_won"), "新事件在册:dig_stop/battle_won〔专长批 V1〕") diff --git a/game/tests/unit/core/encapsulation_p2_sweep_test.gd b/game/tests/unit/core/encapsulation_p2_sweep_test.gd index 3e55fad3..08bd3e76 100644 --- a/game/tests/unit/core/encapsulation_p2_sweep_test.gd +++ b/game/tests/unit/core/encapsulation_p2_sweep_test.gd @@ -11,34 +11,34 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: -# oracle: design/engineering/code-conventions.md:41(封装边界:跨对象往来只走公开方法与属性——P2 词表单点扫描组) +# oracle: design/engineering/code-conventions.md:41 (封装边界:跨对象往来只走公开方法与属性——P2 词表单点扫描组) _sweep_generator() _sweep_production_face() quit(Kit.finish("encapsulation_p2_sweep_test")) func _src(path: String) -> String: -# oracle: design/engineering/code-conventions.md:41(源码采样组) +# oracle: design/engineering/code-conventions.md:41 (源码采样组) var src := FileAccess.get_file_as_string(path) Kit.check("扫描面非空前置:%s" % path, src.length() > 0) return src func _zero(pattern: String, src: String, label: String) -> void: -# oracle: design/engineering/code-conventions.md:41(零命中扫描组) +# oracle: design/engineering/code-conventions.md:41 (零命中扫描组) var re := RegEx.create_from_string(pattern) Kit.check("%s:%s 零命中〔架构P2〕" % [label, pattern], re.search(src) == null) func _anchor(pattern: String, src: String, label: String) -> void: -# oracle: design/engineering/code-conventions.md:41(正锚存在组) +# oracle: design/engineering/code-conventions.md:41 (正锚存在组) var re := RegEx.create_from_string(pattern) Kit.check("%s:%s 正锚在案〔架构P2〕" % [label, pattern], re.search(src) != null) # ① V1 生成器词表定义删除与改指 func _sweep_generator() -> void: -# oracle: design/engineering/code-conventions.md:41(生成器本地副本归零组) +# oracle: design/engineering/code-conventions.md:41 (生成器本地副本归零组) var src := _src("res://core/node_map_generator.gd") if src.length() == 0: return @@ -48,7 +48,7 @@ func _sweep_generator() -> void: # ② V2 生产三目录定义唯一性(递归扫 .gd,恰好 1 处且落 level_table.gd) func _sweep_production_face() -> void: -# oracle: design/engineering/code-conventions.md:41(schema 唯一定点组) +# oracle: design/engineering/code-conventions.md:41 (schema 唯一定点组) var files: Array[String] = [] for dir_path in ["res://core", "res://data", "res://presentation"]: _collect_gd(dir_path, files) diff --git a/game/tests/unit/core/encapsulation_sweep_test.gd b/game/tests/unit/core/encapsulation_sweep_test.gd index 06af956c..e1bbf105 100644 --- a/game/tests/unit/core/encapsulation_sweep_test.gd +++ b/game/tests/unit/core/encapsulation_sweep_test.gd @@ -14,7 +14,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: -# oracle: design/engineering/code-conventions.md:41(封装边界——五处结构性零命中扫描组) +# oracle: design/engineering/code-conventions.md:41 (封装边界——五处结构性零命中扫描组) _sweep_settlement_segments() _sweep_orchestrator_methods() _sweep_breakpoint_pair() @@ -26,7 +26,7 @@ func _init() -> void: # 源文件读取+非空前置(返 "" 即已判红——调用侧跳过后续正则断言) func _src(path: String) -> String: -# oracle: design/engineering/code-conventions.md:41(源码采样组) +# oracle: design/engineering/code-conventions.md:41 (源码采样组) var src := FileAccess.get_file_as_string(path) Kit.check("扫描面非空前置:%s" % path, src.length() > 0) return src @@ -34,21 +34,21 @@ func _src(path: String) -> String: # 正则零命中断言(-pattern 意图写入断言文案——可 grep 定位) func _zero(pattern: String, src: String, label: String, path: String) -> void: -# oracle: design/engineering/code-conventions.md:41(零命中扫描组) +# oracle: design/engineering/code-conventions.md:41 (零命中扫描组) var re := RegEx.create_from_string(pattern) Kit.check("%s:%s 零命中〔封装5.1〕" % [label, pattern], re.search(src) == null) # 正锚在案断言(正则命中 ≥1——新公开面/新形态在用) func _anchor(pattern: String, src: String, label: String, path: String) -> void: -# oracle: design/engineering/code-conventions.md:41(正锚存在组) +# oracle: design/engineering/code-conventions.md:41 (正锚存在组) var re := RegEx.create_from_string(pattern) Kit.check("%s:%s 正锚在案〔封装5.1〕" % [label, pattern], re.search(src) != null) # ① V2 settlement 七文件(束注入换代——对编排器引用归零) func _sweep_settlement_segments() -> void: -# oracle: design/engineering/code-conventions.md:41(结算段封装扫描组) +# oracle: design/engineering/code-conventions.md:41 (结算段封装扫描组) var classes := { "res://core/settlement/grant_segment.gd": "GrantSegment", "res://core/settlement/combat_segment.gd": "CombatSegment", @@ -68,7 +68,7 @@ func _sweep_settlement_segments() -> void: # ② V3 编排器搬家五方法零残留 func _sweep_orchestrator_methods() -> void: -# oracle: design/engineering/code-conventions.md:41(编排器方法面扫描组) +# oracle: design/engineering/code-conventions.md:41 (编排器方法面扫描组) var src := _src("res://core/battle_orchestrator.gd") if src.length() == 0: return @@ -78,7 +78,7 @@ func _sweep_orchestrator_methods() -> void: # ③ V4 断点域(adventure_runner → BreakpointStore 公开面) func _sweep_breakpoint_pair() -> void: -# oracle: design/engineering/code-conventions.md:41(断点对封装扫描组) +# oracle: design/engineering/code-conventions.md:41 (断点对封装扫描组) var src := _src("res://core/adventure_runner.gd") if src.length() == 0: return @@ -88,7 +88,7 @@ func _sweep_breakpoint_pair() -> void: # ④ V5 存档双向公开面(save_manager↔slot_store) func _sweep_save_pair() -> void: -# oracle: design/engineering/code-conventions.md:41(存档对封装扫描组) +# oracle: design/engineering/code-conventions.md:41 (存档对封装扫描组) var src_m := _src("res://core/save_manager.gd") if src_m.length() > 0: _zero("slots\\._", src_m, "save_manager 对槽位件私取归零", "res://core/save_manager.gd") @@ -102,7 +102,7 @@ func _sweep_save_pair() -> void: # ⑤ V6 效果宿主累积面(grant → BattleFxHost 公开累积方法) func _sweep_fx_host_accumulators() -> void: -# oracle: design/engineering/code-conventions.md:41(特效宿主累积面扫描组) +# oracle: design/engineering/code-conventions.md:41 (特效宿主累积面扫描组) var src := _src("res://core/settlement/grant_segment.gd") if src.length() == 0: return @@ -112,7 +112,7 @@ func _sweep_fx_host_accumulators() -> void: # ⑥ V7 配置挂载面(config_db → 三 schema bind_resolver) func _sweep_config_resolver() -> void: -# oracle: design/engineering/code-conventions.md:41(配置挂载面扫描组) +# oracle: design/engineering/code-conventions.md:41 (配置挂载面扫描组) var src := _src("res://core/config_db.gd") if src.length() == 0: return diff --git a/game/tests/unit/core/feat_vouchers_test.gd b/game/tests/unit/core/feat_vouchers_test.gd index cda7db0d..ad9b7b65 100644 --- a/game/tests/unit/core/feat_vouchers_test.gd +++ b/game/tests/unit/core/feat_vouchers_test.gd @@ -16,7 +16,7 @@ func EffectEngineKindProbe(_db) -> bool: func _init() -> void: -# oracle: design/gdd/systems/冒险循环/奇物.md:465(奇物凭证五件与留任二件组) +# oracle: design/gdd/systems/冒险循环/奇物.md:465 (奇物凭证五件与留任二件组) var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): print("[feat_vouchers_test] FAIL — 数值表加载失败") diff --git a/game/tests/unit/core/hero_ledger_test.gd b/game/tests/unit/core/hero_ledger_test.gd index e8e30b4c..ad786cfa 100644 --- a/game/tests/unit/core/hero_ledger_test.gd +++ b/game/tests/unit/core/hero_ledger_test.gd @@ -14,7 +14,7 @@ const LevelRunnerScript := preload("res://core/level_runner.gd") func _init() -> void: -# oracle: design/gdd/systems/冒险循环/冒险结构.md:288(生命一致性:三写入口封顶 [0,生效上限]——主角账组) +# oracle: design/gdd/systems/冒险循环/冒险结构.md:288 (生命一致性:三写入口封顶 [0,生效上限]——主角账组) var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): print("[hero_ledger_test] FAIL — 数值表加载失败") diff --git a/game/tests/unit/core/level_map_type_vis_test.gd b/game/tests/unit/core/level_map_type_vis_test.gd index f97fdd19..9cb4d92d 100644 --- a/game/tests/unit/core/level_map_type_vis_test.gd +++ b/game/tests/unit/core/level_map_type_vis_test.gd @@ -10,7 +10,7 @@ const LevelTableScript := preload("res://data/schemas/level_table.gd") func _init() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176(信息迷雾类型可见性宿主——装载组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176 (信息迷雾类型可见性宿主——装载组) var db = load("res://core/config_db.gd").new() var loaded: bool = db.load_tables("res://data/tables", false) Kit.check_quiet(loaded, "可见性用例:数值表加载成功") @@ -103,7 +103,7 @@ func _runner(db, nodes: Array, anchor_id: int, candidates: Array, n: int = 2): # ---- ⑥ N 进数据表(含越域校验)〔fv6〕---- func _test_field_in_table(db) -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176(迷雾参数读表——字段在表组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176 (迷雾参数读表——字段在表组) var n_in_table: int = int(db.run.level.info_visible_layers) Kit.check("N 落表:level.tres 读数 2(实际 %d)〔fv6〕" % n_in_table, n_in_table == 2) var t := LevelTableScript.new() @@ -127,7 +127,7 @@ func _has_n_domain_err(errs: Array) -> bool: # ---- ① 邻近 N 层见类型(层距边界)〔fv1〕---- func _test_layer_distance(db) -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176(层距 N 可见性组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176 (层距 N 可见性组) var nodes := _graph_nodes() var r = _runner(db, nodes, 1, [nodes[2]]) # 锚 = 节点 1(层 1),候选 = 节点 2 var vis: Array = r.type_visible_ids() @@ -139,7 +139,7 @@ func _test_layer_distance(db) -> void: # ---- ② 下一跳恒可见(跨层跳边候选)〔fv4〕---- func _test_candidate_exempt(db) -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176(候选豁免组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176 (候选豁免组) var nodes := _graph_nodes() var r = _runner(db, nodes, 6, [nodes[3]]) # 锚 = 节点 6(层 5),候选 = 节点 3(层 2,层距 3) var vis: Array = r.type_visible_ids() @@ -150,7 +150,7 @@ func _test_candidate_exempt(db) -> void: # ---- ③ Boss/终点不入雾+⑤ 入口停点锚层 0〔fv3〕〔fv1〕---- func _test_boss_exempt(db) -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176(Boss 豁免组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176 (Boss 豁免组) var nodes := _graph_nodes() var r = _runner(db, nodes, -1, [nodes[0]]) # 入口停点(无当前节点,锚层 0) var vis: Array = r.type_visible_ids() @@ -163,7 +163,7 @@ func _test_boss_exempt(db) -> void: # ---- ④ 单圈回雾(visited 不豁免)〔fv7〕---- func _test_single_circle(db) -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176(单圈可见组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176 (单圈可见组) var nodes := _graph_nodes() var r = _runner(db, nodes, 6, [nodes[7], nodes[3]]) r.visited.assign([nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], nodes[6]]) @@ -176,7 +176,7 @@ func _test_single_circle(db) -> void: # ---- ⑤ 单链退化形态(出度 ≤1 图,编号 = id 句柄)〔fv1〕---- func _test_single_chain_entry(db) -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176(单链入口组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176 (单链入口组) var nodes := _chain_nodes() var r = _runner(db, nodes, -1, [nodes[0]]) var vis: Array = r.type_visible_ids() @@ -189,7 +189,7 @@ func _test_single_chain_entry(db) -> void: # ---- ⑥ N 读表:可见窗随表值随动〔fv6〕---- func _test_n_from_table(db) -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176(N 读表组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:176 (N 读表组) var nodes := _graph_nodes() var r = _runner(db, nodes, 1, [nodes[2]]) # 锚层 1 db.run.level.info_visible_layers = 1 @@ -207,6 +207,7 @@ func _test_n_from_table(db) -> void: # ---- ⑦ 续玩重建同值〔fv7〕---- func _test_resume_rebuild(db) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var t := LevelTableScript.new() t.info_visible_layers = 2 t.rows = [{"level_index": 1, "display_name": "夹具关", "rest_heal_pct": 30}] diff --git a/game/tests/unit/core/level_shop_economy_test.gd b/game/tests/unit/core/level_shop_economy_test.gd index 7fafb4c9..6d7eb724 100644 --- a/game/tests/unit/core/level_shop_economy_test.gd +++ b/game/tests/unit/core/level_shop_economy_test.gd @@ -232,6 +232,7 @@ func _board_row_exact(level_index: int, depth: int) -> bool: func _init() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) _db = ConfigDBScript.new() # 表加载失败不中止(承 G2/G3/G4/G5 同款:表损坏的红落在具体断言上—— # 诊断在此展开,后续断言按坏表实况逐条验红;collect_only=true 下成员照常赋值可评) @@ -261,7 +262,7 @@ func _init() -> void: # ---- 数值入表等价证明(d11/d16a——原字面量迁移:表值 == 迁移前字面量,消费端读表)---- func _smoke_table_migration() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:195(行集纪律——表迁移组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:195 (行集纪律——表迁移组) print("--- 数值入表(shop 两 knob + hero 显示名 · 原值迁移)---") Kit.check("shop.relic_base_price 表值 == 迁移前字面量(15.0)〔wd11〕", _db.run.shop.relic_base_price == 15.0) Kit.check("hero.display_name 表值 == 迁移前字面量(探险者)〔wd16〕", _db.combat.hero.display_name == "探险者") @@ -276,7 +277,7 @@ func _smoke_table_migration() -> void: # 敌侧/板侧解析一律走 ConfigDB 真实消费链,禁直读行集自算)---- func _smoke_generated_coverage() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:184(每终点前恰一店——生成覆盖扫描组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:184 (每终点前恰一店——生成覆盖扫描组) var enemy_ok := true var board_ok := true var boss_band_ok := true @@ -327,7 +328,7 @@ func _smoke_generated_coverage() -> void: # ---- 关卡节点图·生成图推进冒烟(图 = 该关参数档 × 种子)---- func _smoke_level() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178(关卡图校验推进组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178 (关卡图校验推进组) print("--- 关卡节点图·生成图推进(参数档×种子产图·满配冒险成功/恢复公式/败北线/回放确定性)---") var autoplay = load("res://sim/level_autoplay.gd") var hero_base := {"atk": int(_db.combat.hero.atk), "hp": int(_db.combat.hero.max_hp), "ac": int(_db.combat.hero.armor_class)} # 配置基线快照——⑤ 回基线对比用(改表自动跟随,不再硬编码) @@ -441,7 +442,7 @@ func _drive_to_rest(level_index: int, seed_val: int, gap: int) -> Dictionary: # ---- 分支节点图冒烟:图合法性校验 + L2 幽暗地域生成图行进(图 = 参数档 × 种子)---- func _smoke_level_graph() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178(图结构与行进纪律组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178 (图结构与行进纪律组) print("--- 关卡节点图·分支节点图(L2 幽暗地域·生成图)---") var autoplay = load("res://sim/level_autoplay.gd") # ① 关卡表行级校验零错误(关卡表只承载序号/显示名/恢复比例——图合法性由 validate_graph 在起关时承担) @@ -799,7 +800,7 @@ func _fresh_rng(seed_val: int): # ---- ① GP 冒险钱包·到账 ---- func _smoke_gp_wallet() -> void: -# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:233(GP 钱包入账组) +# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:233 (GP 钱包入账组) print("--- GP 冒险钱包·到账(战斗完成入账恰一次 + Boss 加值)---") var autoplay = load("res://sim/level_autoplay.gd") # ① L1 首战(普通战档——掷定 [2,4] + 关级加值 0):runner 驱动,收集 battle_finished 与钱包事件 @@ -865,7 +866,7 @@ func _escrow_sum_of(rows: Array) -> int: # ---- ② escrow 隔离(GP安全格兑付 / 破财直验 / 钱包 clamp)---- func _smoke_gp_escrow() -> void: -# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:233(GP escrow 组) +# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:233 (GP escrow 组) print("--- GP escrow 隔离(GP安全格兑付入缓冲 · 破财不透支)---") # ① 种子扫描:找GP 袋(gp 型安全格)可挖掘局——挖开兑付 +3 入 escrow,战斗末随 gp_dropped 一次上抛 var scan := {} @@ -979,7 +980,7 @@ func _find_gp_dig(minesweeper, settlement) -> Dictionary: # ---- ③ 商店房三收口 ---- func _smoke_shop_room() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:184(商店房呈现组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:184 (商店房呈现组) print("--- 商店房三收口(现价/加算区/余额不足拒/离开回选路/收束清零)---") var autoplay = load("res://sim/level_autoplay.gd") # 行进到商店房(按图型别定位商店节点——候选取最小句柄行进,到达即停): @@ -1113,7 +1114,7 @@ func _shop_products_by_id(prods: Array) -> Dictionary: # ---- ④ 商店编排性质(生成图扫描面——三条性质 + 终点跨表解析)---- func _smoke_shop_graph() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:184(必经恰一店图纪律组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:184 (必经恰一店图纪律组) print("--- 商店编排性质(每终点前一位恰一店 · 店数=终点数 · 全路径恰穿一店)---") var pred_bad := 0 var term_total := 0 @@ -1184,7 +1185,7 @@ func _smoke_shop_graph() -> void: # ---- ⑥ 大岔口分区域兑付(V3——多终点图走哪条路决定打谁,任一 Boss 胜即收束恰一次)---- func _smoke_multi_terminal_settlement() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:185(多终局收束组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:185 (多终局收束组) print("--- 大岔口分区域兑付(L2 两轴各打各的终点)---") var autoplay = load("res://sim/level_autoplay.gd") var nodes: Array = _generated_graph(2, 42).get("nodes", []) @@ -1252,7 +1253,7 @@ func _paths_all_one_shop(nodes: Array) -> bool: # ---- ⑤ 商店共享池(三选一同构/乘法价/跨渠道共账/切边/断点扩键)---- func _smoke_shop_pool() -> void: -# oracle: design/engineering/architecture/architecture.md:107(商店共享池组) +# oracle: design/engineering/architecture/architecture.md:107 (商店共享池组) print("--- 商店共享池(抽3买1全重抽 · 乘法定价 ceil · 池空硬闸 · 切边零入店)---") var autoplay = load("res://sim/level_autoplay.gd") var shelf_kinds: Array = [] @@ -1415,7 +1416,7 @@ func _smoke_shop_pool() -> void: # ---- 商店房 node_entered 载荷(尾波 V1——_enter_node pool/legacy 双发射路径归一后的行为保持断言)---- func _test_shop_node_entered_payload() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:184(行进至此打开商店覆盖层——载荷组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:184 (行进至此打开商店覆盖层——载荷组) print("--- 商店房 node_entered 载荷(pool 含 shelf:true+gp 现值/legacy 无 shelf 键)---") var autoplay = load("res://sim/level_autoplay.gd") # pool 态:载荷字典经信号闭包当场取样(字典为引用累积器——lambda 按值捕获标量的绕行惯例) @@ -1574,7 +1575,7 @@ func _has_err_category(errs: Array, category: String) -> bool: # ---- 货架位数读表(架构整改——shelf_size 表头单点:进店与重抽同源)---- func _test_shelf_size_from_table() -> void: -# oracle: design/gdd/ux/shop.md:13(货架位数读表组) +# oracle: design/gdd/ux/shop.md:13 (货架位数读表组) var autoplay = load("res://sim/level_autoplay.gd") var st = _db.run.shop var saved: int = int(st.shelf_size) @@ -1596,7 +1597,7 @@ func _test_shelf_size_from_table() -> void: # ---- 散折价收回规则键(架构整改 R2——shop.spend_discount 表字段退役,折价读 economy_spend.discount_pct)---- func _test_spend_discount_from_rule_key() -> void: -# oracle: design/gdd/systems/排雷循环/行动经济.md:256(换图基座:挖格产 RAP 与刷新折扣组) +# oracle: design/gdd/systems/排雷循环/行动经济.md:256 (换图基座:挖格产 RAP 与刷新折扣组) # 字段真删:shop.tres 加载零诊断 + spend_discount 属性不在位 Kit.check("shop.tres 加载零诊断(spend_discount 字段真删——schema 与表行同卸)〔架构整改 V2〕", _db.diagnostics_count("error") == 0 and _db.run.shop.get("spend_discount") == null) diff --git a/game/tests/unit/core/level_table_validate_test.gd b/game/tests/unit/core/level_table_validate_test.gd index b845d220..14201d91 100644 --- a/game/tests/unit/core/level_table_validate_test.gd +++ b/game/tests/unit/core/level_table_validate_test.gd @@ -11,7 +11,7 @@ const LevelTableScript := preload("res://data/schemas/level_table.gd") func _init() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178(关卡表消费侧校验宿主) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178 (关卡表消费侧校验宿主) _test_positive() _test_negative() _test_scope_not_extended() @@ -38,7 +38,7 @@ func _has(errs: Array, cat: String, needle: String = "") -> bool: # ---- 正例(四检全过)---- func _test_positive() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178(良构基底正向组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178 (良构基底正向组) # 多入口多终点:两入口共汇入一岔口,两终点各在互异深度 var multi := [ _n(0, "battle", 0, [2]), _n(1, "battle", 0, [2]), @@ -61,7 +61,7 @@ func _test_positive() -> void: # ---- 负例九类(各报对应类别与判据消息)---- func _test_negative() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178(违规配置加载期致命——负向组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178 (违规配置加载期致命——负向组) var non_boss_end := [_n(0, "battle", 0, [1]), _n(1, "battle", 1, [])] Kit.check("负例:终点非 Boss 命中「终点恒为 Boss」〔v1〕", _has(_errs(non_boss_end), "structural", "终点 1 非 Boss")) @@ -95,7 +95,7 @@ func _test_negative() -> void: # ---- 「勿扩勿缩」反证:本检不含商店位与个数对参数档的核对 ---- func _test_scope_not_extended() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178(校验范围不外扩组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178 (校验范围不外扩组) # 合法形状但全程无商店/三个终点同入口图——四检不该因此报错(商店位归冒烟断言、个数归产出侧) var no_shop := [_n(0, "battle", 0, [1, 2]), _n(1, "battle", 1, [3]), _n(2, "rest", 1, [3]), _n(3, "boss", 2, [])] Kit.check("范围反证:无商店图不在加载校验内报错(商店位由冒烟断言把关)〔v1〕", _errs(no_shop).is_empty()) diff --git a/game/tests/unit/core/meta_progression_forge_test.gd b/game/tests/unit/core/meta_progression_forge_test.gd index 1e4af588..35c769f6 100644 --- a/game/tests/unit/core/meta_progression_forge_test.gd +++ b/game/tests/unit/core/meta_progression_forge_test.gd @@ -133,7 +133,7 @@ func _auto_play_round(settlement, out: Dictionary) -> void: # ---- 元进度 ②树购买面(购买受理/持久/余额不足拒绝/未知节点拒绝; # 行价=表值 flat 单价)---- func _meta_pricing_and_buy() -> void: -# oracle: design/gdd/systems/跨局循环/天赋树.md:198(单币可判:购买只扣钥石、余额不足拒绝零变化组) +# oracle: design/gdd/systems/跨局循环/天赋树.md:198 (单币可判:购买只扣钥石、余额不足拒绝零变化组) print("--- 元进度·树购买面(隔离档 smoke_meta_buy/dry)---") _meta_smoke_cleanup() var sv = _meta_new_save(_META_SMOKE_PATHS[0]) @@ -160,7 +160,7 @@ func _meta_pricing_and_buy() -> void: # ---- 元进度 ⑥Boss 两档 ⑦钥石不丢 ⑧工坊解锁 ⑩摘要副本与 cap(合成摘要驱动——settle 纯账面零跑局)---- func _meta_settle_and_workshop() -> void: -# oracle: design/gdd/systems/跨局循环/元进度.md:150(钥石收束入账不丢组) +# oracle: design/gdd/systems/跨局循环/元进度.md:150 (钥石收束入账不丢组) print("--- 元进度·收束入账与工坊(隔离档 smoke_meta_settle/workshop/cap)---") var sv = _meta_new_save(_META_SMOKE_PATHS[2]) var mp = load("res://core/meta_progression.gd").new(_db, sv) @@ -353,7 +353,7 @@ func _meta_settle_and_workshop() -> void: # ---- 元进度 ④注入可见 + 白板成立(验收 4/2/3——程序面;MC 逐位回归归 T7 全量验证)---- func _meta_injection() -> void: -# oracle: design/gdd/systems/跨局循环/天赋树.md:201(注入可判:开局覆盖值分层可加组) +# oracle: design/gdd/systems/跨局循环/天赋树.md:201 (注入可判:开局覆盖值分层可加组) print("--- 元进度·注入可见与白板(隔离档 smoke_meta_white/dry)---") var sv = _meta_new_save(_META_SMOKE_PATHS[1]) var mp = load("res://core/meta_progression.gd").new(_db, sv) @@ -397,7 +397,7 @@ func _meta_injection() -> void: # ---- 锻造工坊·两根类型轴所有权移交(V5 前半:hero.tres 两轴删除+锻造配置默认值)---- # 后半(build_adventure_params 注入默认值/选中覆盖)随 T4 注入接线同批断言;写口/解锁面归 T3。 func _smoke_forge_axes() -> void: -# oracle: design/gdd/systems/跨局循环/锻造工坊.md:220(锻造两轴单选注入与树零攻防组) +# oracle: design/gdd/systems/跨局循环/锻造工坊.md:220 (锻造两轴单选注入与树零攻防组) print("--- 锻造工坊·类型轴所有权移交(T2)---") # V5:hero.tres 静态表两轴已删(全表加载零违例——config_db_test 同款闸;此处钉字段不在位) Kit.check("hero.tres 无 attack_type/armor_type 字段(契约 2——静态表两轴删除)〔锻造工坊批 V5〕", @@ -560,7 +560,7 @@ func _smoke_forge_axes() -> void: # ---- 天赋树冒烟(v0.8 12 节点:schema/购买面/Fork 一节点双态/彩蛋特化)---- func _smoke_tree() -> void: -# oracle: design/gdd/systems/跨局循环/天赋树.md:194(天赋树购买与六键合成组) +# oracle: design/gdd/systems/跨局循环/天赋树.md:194 (天赋树购买与六键合成组) print("--- 天赋树(12 节点 · 购买面 · Fork 双态 · 彩蛋觉醒)---") # 〔V1〕结构:12 行 + schema 零违例 Kit.check("meta_tree 已加载(12 节点=脊柱 2〔生命/命中淬炼一线一节点 cap4〕+锻造 2〔钥匙+彩蛋——彩蛋含在锻造 2 内非第 13 行〕+钥石 2〔秘宝匣/刷新升级〕+同调 6〔socket 3+Fork 3 双态〕——v0.8 终态)〔天赋树批 V1〕", @@ -643,7 +643,7 @@ func _smoke_tree() -> void: # ---- 天赋树六键行为冒烟(V10:开局姿态窗/危险直觉限次/财富之道聚散/守侧失误补偿; # 引擎直构 + 编排授予段直注(_grant_seg._judge_seal=结算授予段封印判定单口))---- func _smoke_tree_rules() -> void: -# oracle: design/gdd/systems/跨局循环/天赋树.md:194(规则键参数读表组) +# oracle: design/gdd/systems/跨局循环/天赋树.md:194 (规则键参数读表组) print("--- 天赋树六键行为(V10:窗/限次/聚散/守侧)---") # 开局姿态组:每关首轮窗(battle_index 事实——引擎直构 + 自建 ctx) var fx = load("res://core/effect_engine.gd").new(null) @@ -784,7 +784,7 @@ func _smoke_tree_rules() -> void: # ---- 锻造契约补齐(断言补齐批——⑥锻造工坊):拒购零副作用/祝福件零泄漏/默认值解耦/甲型双轴 ---- func _test_forge_buy_reject() -> void: -# oracle: design/gdd/systems/跨局循环/锻造工坊.md:222(钥石不足购买被拒、余额与等级零变化组) +# oracle: design/gdd/systems/跨局循环/锻造工坊.md:222 (钥石不足购买被拒、余额与等级零变化组) var sv = _meta_new_save("user://smoke_meta_reject.json") var mp = load("res://core/meta_progression.gd").new(_db, sv) sv.meta_state._add_keystone(10) # 低于首购价 20——余额不足面 @@ -799,7 +799,7 @@ func _test_forge_buy_reject() -> void: func _test_blessing_no_forge_leak() -> void: -# oracle: design/gdd/systems/跨局循环/锻造工坊.md:220(树淬炼对攻击与 AC 零贡献组) +# oracle: design/gdd/systems/跨局循环/锻造工坊.md:220 (树淬炼对攻击与 AC 零贡献组) var sv = _meta_new_save("user://smoke_meta_blessing.json") var mp = load("res://core/meta_progression.gd").new(_db, sv) var fs0: Dictionary = sv.meta_state.forge_state().duplicate(true) @@ -818,7 +818,7 @@ func _test_blessing_no_forge_leak() -> void: func _test_default_axes_pre_key() -> void: -# oracle: design/gdd/systems/跨局循环/锻造工坊.md:217(未点亮期间默认值照常注入组) +# oracle: design/gdd/systems/跨局循环/锻造工坊.md:217 (未点亮期间默认值照常注入组) var sv = _meta_new_save("user://smoke_meta_axesw.json") var mp = load("res://core/meta_progression.gd").new(_db, sv) var ax: Dictionary = mp.hero_type_axes() @@ -827,7 +827,7 @@ func _test_default_axes_pre_key() -> void: func _test_armor_switch_dual_axes() -> void: -# oracle: design/gdd/systems/跨局循环/锻造工坊.md:221(换装不丢级不生效——双轴组) +# oracle: design/gdd/systems/跨局循环/锻造工坊.md:221 (换装不丢级不生效——双轴组) var sv = _meta_new_save("user://smoke_meta_axesw.json") sv.meta_state._add_keystone(1000) var mp = load("res://core/meta_progression.gd").new(_db, sv) diff --git a/game/tests/unit/core/minesweeper_rules_test.gd b/game/tests/unit/core/minesweeper_rules_test.gd index cb3b50ba..c6d52fd4 100644 --- a/game/tests/unit/core/minesweeper_rules_test.gd +++ b/game/tests/unit/core/minesweeper_rules_test.gd @@ -17,7 +17,7 @@ var _ae: ActionEconomy func _init() -> void: -# oracle: design/gdd/systems/排雷循环/排雷玩法.md:224(排雷规则宿主——装载组) +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:224 (排雷规则宿主——装载组) _db = load("res://core/config_db.gd").new() as ConfigDb if not _db.load_tables("res://data/tables", false): Kit.check("数值表加载", false) @@ -46,7 +46,7 @@ func _init() -> void: func _test_install_invariants() -> void: -# oracle: design/gdd/systems/排雷循环/排雷玩法.md:228(装板四不变式组) +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:228 (装板四不变式组) _rules.install_board(_board) Kit.check("装板后 current_board 即所装棋盘", _rules.current_board() == _board) var opened: int = _rules.revealed_cells().size() @@ -70,7 +70,7 @@ func _unrevealed_safe() -> Vector2i: func _test_dig_face_rules() -> void: -# oracle: design/gdd/systems/排雷循环/排雷玩法.md:231(挖/封印合法性与可辨拒绝组) +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:231 (挖/封印合法性与可辨拒绝组) var revealed_first = _rules.revealed_cells()[0] as Vector2i var out: Array = _rules.settle_batch([{"action": "dig", "cell": revealed_first}]) var o: Dictionary = (out[0] as Dictionary) if not out.is_empty() else {} @@ -85,7 +85,7 @@ func _test_dig_face_rules() -> void: func _test_reveal_advances() -> void: -# oracle: design/gdd/systems/排雷循环/排雷玩法.md:230(揭示推进与连锁组) +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:230 (揭示推进与连锁组) var c := _unrevealed_safe() if c == Vector2i(-1, -1): Kit.check("存在未揭示安全格(揭示推进前置)", false) @@ -99,7 +99,7 @@ func _test_reveal_advances() -> void: func _test_seal_place() -> void: -# oracle: design/gdd/systems/排雷循环/排雷玩法.md:231(重复封印拒绝组) +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:231 (重复封印拒绝组) var c := _unrevealed_safe() if c == Vector2i(-1, -1): Kit.check("存在未揭示安全格(封印前置)", false) @@ -112,7 +112,7 @@ func _test_seal_place() -> void: func _test_reject_out_of_catalog() -> void: -# oracle: design/gdd/systems/排雷循环/排雷玩法.md:236(目录外拒绝组) +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:236 (目录外拒绝组) var out: Array = _rules.settle_batch([{"action": "not_a_real_action", "cell": Vector2i(0, 0)}]) var o: Dictionary = (out[0] as Dictionary) if not out.is_empty() else {} Kit.check("目录外意图被拒(不静默吞掉)——实际载荷 %s" % str(o).substr(0, 80), @@ -122,7 +122,7 @@ func _test_reject_out_of_catalog() -> void: # ---- V14 棋盘揭示预览只读口(架构整改——preview_reveal 与实挖揭示集同口径、零状态写入零事件)---- func _test_preview_reveal_readonly() -> void: -# oracle: design/engineering/architecture/architecture.md:103(preview_reveal 只读预览口——零写入零事件组) +# oracle: design/engineering/architecture/architecture.md:103 (preview_reveal 只读预览口——零写入零事件组) var events := 0 _rules.cell_revealed.connect(func(_evt): events += 1) # 零发射哨兵(preview 全程不触发揭示事件) # 形态 A:封印在场——preview(未开格) 不越封印且零状态写入 diff --git a/game/tests/unit/core/node_map_generator_test.gd b/game/tests/unit/core/node_map_generator_test.gd index c57b11a9..403bdc3a 100644 --- a/game/tests/unit/core/node_map_generator_test.gd +++ b/game/tests/unit/core/node_map_generator_test.gd @@ -16,6 +16,7 @@ var _gen func _init() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) _db = ConfigDBScript.new() var load_ok: bool = _db.load_tables("res://data/tables", true) if not load_ok: @@ -77,7 +78,7 @@ func _max_depth(g: Dictionary) -> int: # ---- V1 产出合格:三档×种子扫描,自证零错误 ---- func _test_output_ok() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:129(产出约束六条+结构铁律组) +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:129 (产出约束六条+结构铁律组) var all_ok := true var entry_exit_ok := true for L in [1, 2, 3]: @@ -95,7 +96,7 @@ func _test_output_ok() -> void: # ---- V3 可复现:纯函数+counter 无关 ---- func _test_reproducible() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:134(同种子同参数同图组) +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:134 (同种子同参数同图组) var same := true for L in [1, 2, 3]: if _sig(_graph(L, 42)) != _sig(_graph(L, 42)): @@ -126,7 +127,7 @@ func _test_reproducible() -> void: # ---- V5 岔路取舍两条 ---- func _test_fork_rules() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:88(岔路取舍组) +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:88 (岔路取舍组) var next_hop_ok := true var comp_ok := true for L in [1, 2, 3]: @@ -202,7 +203,7 @@ func _branch_types(g: Dictionary, head_id: int, sibling_outs: Array) -> Array: # ---- V6 必经恰一店+归属锁定+多终点深度互异 ---- func _test_shop_and_attribution() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:48(必经恰一店与归属锁定组) +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:48 (必经恰一店与归属锁定组) var paths_ok := true var lock_ok := true var depth_ok := true @@ -255,7 +256,7 @@ func _all_paths(g: Dictionary) -> Array: # ---- V7 战斗保底 ---- func _test_battle_floor() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:129(战斗保底组) +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:129 (战斗保底组) var ok := true for L in [1, 2, 3]: for s in range(42, 52): @@ -267,7 +268,7 @@ func _test_battle_floor() -> void: # ---- V9 含岔口与出口结构 ---- func _test_exit_structure() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:48(出口结构与分支互斥组) +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:48 (出口结构与分支互斥组) var fork_all := true var l1_single := true var big_fork_ok := true @@ -314,7 +315,7 @@ func _terminals_reachable(g: Dictionary, id: int) -> int: # ---- V9 Boss 出场门控(难度曲线与Boss——每区域恰一 Boss 终点)---- func _test_boss_exit_per_region() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:48(每区域 Boss 出口组) +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:48 (每区域 Boss 出口组) # 真实生成多区域图:全部终点 type=="boss"、boss 终点数==exit_count、深度=L−r(r∈[0,exit_count) # ——每区域恰一 boss、深度互异即分属不同区域) # 节点 depth 字段=入口起最长路径深(生成器校验轴);区域序号 r 的可观测形态=最深 boss(r=0) @@ -350,7 +351,7 @@ func _test_boss_exit_per_region() -> void: # ---- V10 RNG 单点(纯流面 counter 不变)---- func _test_rng_single_point() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:134(RNG 单点流组) +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:134 (RNG 单点流组) var svc = RngScript.new() svc.new_adventure(4242) var before: int = svc.counter() @@ -365,7 +366,7 @@ func _test_rng_single_point() -> void: # ---- V1 违规夹具:各报对应错误类别 ---- func _test_negative_fixtures() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:198(无解 fail-fast 夹具组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:198 (无解 fail-fast 夹具组) # 夹具构造器:手写 nodes/entries/terminals var dup := _fx([ {"id": 0, "type": "battle", "depth": 0, "next": [1]}, @@ -492,7 +493,7 @@ func _has_msg(errs: Array, needle: String) -> bool: # ---- V6 节点图三参数表值驱动(架构整改——fork_third_way_pct/fill_rest_first_pct/width_max 入 level_gen_params)---- func _test_gen_params_table_driven() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:129(参数档读表驱动组) +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:129 (参数档读表驱动组) # ① 同种子真实表行产图逐位(表值驱动回归锚) var g1 := _graph(2, 42) var g2 := _graph(2, 42) diff --git a/game/tests/unit/core/node_map_growth_test.gd b/game/tests/unit/core/node_map_growth_test.gd index 864b8674..570ebce6 100644 --- a/game/tests/unit/core/node_map_growth_test.gd +++ b/game/tests/unit/core/node_map_growth_test.gd @@ -12,6 +12,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) if OS.get_cmdline_user_args().has("fatal-fixture"): _trigger_fatal() return @@ -38,7 +39,7 @@ func _reading(gen, db, L: int) -> Dictionary: # ---- V8 生长递增(三档×多种子逐档读数)---- func _test_growth(gen, db) -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:130(生长递增组) +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:130 (生长递增组) var steps_ok := true var count_ok := true for s in [42, 43, 44, 45, 46]: @@ -62,7 +63,7 @@ func _test_growth(gen, db) -> void: # ---- V4 参数无解判定(静态面:域/预算无解夹具必须被 check_params 拦下)---- func _test_fail_fast_static(gen, db) -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:198(参数无解静态拒绝组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:198 (参数无解静态拒绝组) Kit.check("生产三档参数档可行性判定零错误〔fv4〕", NodeMapGenerator.check_params(db.run.level_gen_params.row_by_level_index(1)).is_empty() and NodeMapGenerator.check_params(db.run.level_gen_params.row_by_level_index(3)).is_empty()) @@ -81,7 +82,7 @@ func _test_fail_fast_static(gen, db) -> void: # ---- V4 致命中止真实通道(子进程退出码非零;零回退分支=件核)---- func _test_fatal_subprocess() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:199(无解致命子进程组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:199 (无解致命子进程组) var bin := _engine_bin() if bin == "": Kit.check("未找到引擎二进制,致命子进程通道未跑(如实标注)〔fv4〕", false) @@ -97,6 +98,7 @@ func _test_fatal_subprocess() -> void: func _trigger_fatal() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var gen = GenScript.new(RngScript.new()) # 域内合法但深度预算无解:层深 6 放三出口(check_params 拦下 → 致命中止) var unsolvable := {"layers": 6, "branch_density": 0.0, "battle_ratio": 0.5, "reward_ratio": 0.2, diff --git a/game/tests/unit/core/playtest_logger_guard_test.gd b/game/tests/unit/core/playtest_logger_guard_test.gd index 670be3ab..41c5bdfc 100644 --- a/game/tests/unit/core/playtest_logger_guard_test.gd +++ b/game/tests/unit/core/playtest_logger_guard_test.gd @@ -13,7 +13,7 @@ func _init() -> void: func _smoke_required_injection() -> void: -# oracle: design/engineering/code-conventions.md:40(拆分交接:依赖构造期一次交付——日志器必填注入守卫组) +# oracle: design/engineering/code-conventions.md:40 (拆分交接:依赖构造期一次交付——日志器必填注入守卫组) # 未注入(缺省 0):start_session 返回空串、零文件产出 var lg0 = load("res://presentation/playtest_logger.gd").new() var p0: String = lg0.start_session(42) diff --git a/game/tests/unit/core/pool_case_d_test.gd b/game/tests/unit/core/pool_case_d_test.gd index 814af348..96002e48 100644 --- a/game/tests/unit/core/pool_case_d_test.gd +++ b/game/tests/unit/core/pool_case_d_test.gd @@ -9,7 +9,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: -# oracle: design/engineering/architecture/architecture.md:107(池结构案 D:候选抽取与池纪律组) +# oracle: design/engineering/architecture/architecture.md:107 (池结构案 D:候选抽取与池纪律组) var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): print("[pool_case_d_test] FAIL — 数值表加载失败") @@ -66,7 +66,7 @@ func _tiers_of(cands: Array) -> Array: func check_v7(a, db) -> void: -# oracle: design/engineering/architecture/architecture.md:107(池案 D V7 组) +# oracle: design/engineering/architecture/architecture.md:107 (池案 D V7 组) if not a.start_adventure(201): Kit.check_quiet(false, "V7 前置:冒险启动") return @@ -112,7 +112,7 @@ func check_v7(a, db) -> void: func check_v6(b, db) -> void: -# oracle: design/engineering/architecture/architecture.md:107(池案 D V6 组) +# oracle: design/engineering/architecture/architecture.md:107 (池案 D V6 组) if not b.start_adventure(202): Kit.check_quiet(false, "V6 前置:冒险启动") return @@ -142,7 +142,7 @@ func check_v6(b, db) -> void: func check_v12(m, db) -> void: -# oracle: design/engineering/architecture/architecture.md:107(池案 D V12 组) +# oracle: design/engineering/architecture/architecture.md:107 (池案 D V12 组) if not m.start_adventure(401): Kit.check_quiet(false, "V12 前置:冒险启动") return @@ -161,7 +161,7 @@ func check_v12(m, db) -> void: func check_v8(c, db) -> void: -# oracle: design/engineering/architecture/architecture.md:107(池案 D V8 组) +# oracle: design/engineering/architecture/architecture.md:107 (池案 D V8 组) if not c.start_adventure(203): Kit.check_quiet(false, "V8 前置:冒险启动") return diff --git a/game/tests/unit/core/run_time_fatal_test.gd b/game/tests/unit/core/run_time_fatal_test.gd index 0178c303..4df2ce6a 100644 --- a/game/tests/unit/core/run_time_fatal_test.gd +++ b/game/tests/unit/core/run_time_fatal_test.gd @@ -20,7 +20,7 @@ const TAG_OK := "board_gen" # 在册合法标签(PURPOSE_TAGS 含;wr7 必 func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/数据配置.md:199(运行期违约通道——致命真的会死组) +# oracle: design/gdd/systems/表现与支撑/数据配置.md:199 (运行期违约通道——致命真的会死组) var db = ConfigDBScript.new() if not db.load_tables("res://data/tables", true): push_error("[run_time_fatal_test] 表加载失败——夹具不可用(回归)") @@ -45,6 +45,7 @@ func _init() -> void: # 缺省形态(契约 2):不接组装点的协作件违约只落自身 push_error+assert,不外溢封印 func _default_form(db) -> bool: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var rng = RngScript.new() rng.set_master_seed(3) var oc = OrchestratorScript.new(db, rng) @@ -69,6 +70,7 @@ func _default_form(db) -> bool: # (棋盘生成半边:装板域拆件后生成器随 BoardInstaller 件内自建——组装点=引用束 fatal_cb 接线, # 经新组装点构建后触发生成器违约,封印传导断言不变) func _seal_propagation(db) -> bool: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var rng_a = RngScript.new() rng_a.set_master_seed(5) var oc_bg = OrchestratorScript.new(db, rng_a) @@ -90,6 +92,7 @@ func _seal_propagation(db) -> bool: # ②wr6(p6):未知用途标签 → handler 记录位为真(判据主体)+拿不到可用 RNG;合法标签对照另行验过 func _unknown_tag_channel() -> bool: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var rng_bad = RngScript.new() rng_bad.set_master_seed(7) if not _inject_handler(rng_bad, "wr6"): @@ -108,6 +111,7 @@ func _unknown_tag_channel() -> bool: # ③wr7(p7):未播种取数 → handler 记录位为真+拿不到可用 RNG;同标签播种对照另行验过 func _unseeded_channel() -> bool: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var rng_bad = RngScript.new() # 不播种(_master_seed 缺省 -1) if not _inject_handler(rng_bad, "wr7"): return false @@ -125,6 +129,7 @@ func _unseeded_channel() -> bool: # 成员在位前提检查(成员被移除时走干净退出 2,不落「赋值不存在的属性」式中途中断) func _inject_handler(rng, label: String) -> bool: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) if not (rng.get("violation_handler") is Callable): push_error("[run_time_fatal_test/%s] violation_handler 成员缺失(p6/p7 形态未实装——回归)" % label) return false diff --git a/game/tests/unit/core/save_boot_no_activate_test.gd b/game/tests/unit/core/save_boot_no_activate_test.gd index 262b88b7..87aced80 100644 --- a/game/tests/unit/core/save_boot_no_activate_test.gd +++ b/game/tests/unit/core/save_boot_no_activate_test.gd @@ -22,7 +22,7 @@ func _init() -> void: # ① 无参实例(autoload 实例化形态)=无激活态+默认合法空态(sv2 类级) func _test_no_arg_instance_has_no_activation() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61(启动态无激活不读写组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61 (启动态无激活不读写组) var sm := SaveManagerScript.new() Kit.check_quiet(sm.slots.active_slot() == 0 and not sm.slots.has_write_target(), "sv2 无参实例无激活态(路径空/激活号 0/写盘目标空)〔卡① sv2〕") @@ -41,7 +41,7 @@ func _test_no_arg_instance_has_no_activation() -> void: # 判别锚:空 _path 的退化写目标=裸 ".tmp"(落 res://,拆闸实验实测杂散落点)—— # 断言先清退化目标再核零新增,闸短路缺陷(拒绝口旁路、写盘真实发生)必红。 func _test_write_rejected_without_target() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61(无激活态写盘拒绝组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61 (无激活态写盘拒绝组) var sm := SaveManagerScript.new() var before := {} for i in range(1, 4): @@ -81,7 +81,7 @@ func _test_write_rejected_without_target() -> void: # (生产结算链全段在位:mark_first_adventure_done→apply_adventure_summary→refresh_treasure_unlocks # →write_to_disk;无激活态下落账内存、写盘拒绝、盘面零触碰——已知中间态的机检面) func _test_settle_chain_write_rejected() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61(结算链写盘拒绝组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61 (结算链写盘拒绝组) var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): Kit.check_quiet(false, "sv3 链测试前置:数值表加载失败〔卡① sv3〕") @@ -104,7 +104,7 @@ func _test_settle_chain_write_rejected() -> void: # ③ 越界槽号三原语拒绝+窥视越界返回不可读(原语边界 fail-safe) func _test_out_of_range_slots_rejected() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61(三存档位域界——越域槽拒绝组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61 (三存档位域界——越域槽拒绝组) var sm := SaveManagerScript.new() sm.slots.attach_slot_template("user://smoke_boot_noact_%d.json") Kit.check_quiet(not sm.slots.activate_slot(0) and not sm.slots.activate_slot(4) diff --git a/game/tests/unit/core/save_manager_domain_test.gd b/game/tests/unit/core/save_manager_domain_test.gd index bb47f190..643d4c3a 100644 --- a/game/tests/unit/core/save_manager_domain_test.gd +++ b/game/tests/unit/core/save_manager_domain_test.gd @@ -19,6 +19,7 @@ var _db func _init() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) _db = ConfigDBScript.new() # 表加载失败不中止(承 G2–G5 同款:表损坏的红落在具体断言上) var load_ok: bool = _db.load_tables("res://data/tables", true) @@ -46,7 +47,7 @@ func _fresh_rng(seed_val: int): # 损坏兜底/迁移链/域界干净/摘要 cap/摘要集成/生涯终身计数域 v6)。测试文件统一 user://smoke_save_*.json 隔离, # 段首清场+段尾清理——绝不碰 user://save.json(红线)。 func _smoke_save() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:176(存档域读写往返/迁移链/损坏兜底/域界组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:176 (存档域读写往返/迁移链/损坏兜底/域界组) print("--- SaveManager 存档读写/迁移/兜底 ---") var sm_script = load("res://core/save_manager.gd") var paths := ["user://smoke_save_roundtrip.json", "user://smoke_save_fresh.json", @@ -339,7 +340,7 @@ func _smoke_save() -> void: # 测试文件统一 user://smoke_save_slot_%d.json 模板隔离(attach_slot_template 注入口——禁各自拼槽名), # 段首清场+段尾清理——绝不碰 user://save.json 与真实槽 user://save_slot_N.json(红线)。 func _smoke_save_slots() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61(三槽位与摘要 cap——槽位域组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61 (三槽位与摘要 cap——槽位域组) print("--- SaveManager 三存档位承载(迭代 33 卡①)---") var sm_script = load("res://core/save_manager.gd") var slot_tpl := "user://smoke_save_slot_%d.json" diff --git a/game/tests/unit/core/save_slot_isolation_test.gd b/game/tests/unit/core/save_slot_isolation_test.gd index 6afdd4fe..743d77c1 100644 --- a/game/tests/unit/core/save_slot_isolation_test.gd +++ b/game/tests/unit/core/save_slot_isolation_test.gd @@ -38,7 +38,7 @@ func _write_v7_keystone(path: String, keystone: int) -> void: # ① 三槽往返:各槽写异值 → 写盘 → 新实例按位读回逐域相等;改槽 1 槽 2 字节不动(sv1) func _test_three_slot_roundtrip_and_isolation() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61(三槽位独立文件隔离组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61 (三槽位独立文件隔离组) var t := SaveManagerScript.new() t.slots.attach_slot_template(TPL) for i in range(1, 4): @@ -66,7 +66,7 @@ func _test_three_slot_roundtrip_and_isolation() -> void: # ② 高版本槽进档失败:拒绝+恢复切换前三态(路径/激活号/数据)+拒读槽零误写(sv9/sv10) func _test_activate_failure_restores_previous_slot() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61(激活失败回滚组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:61 (激活失败回滚组) var t := SaveManagerScript.new() t.slots.attach_slot_template(TPL) _write_v7_keystone(TPL % 1, 311) @@ -88,7 +88,7 @@ func _test_activate_failure_restores_previous_slot() -> void: # ③ MetaProgression 宿主链切槽:引用同一性保持+写盘落当前槽(sv10——禁换实例先例) func _test_metaprogression_reference_identity() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:176(元进度引用同一性——往返一致组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:176 (元进度引用同一性——往返一致组) var t := SaveManagerScript.new() t.slots.attach_slot_template(TPL) _write_v7_keystone(TPL % 1, 533) diff --git a/game/tests/unit/core/save_slot_summary_test.gd b/game/tests/unit/core/save_slot_summary_test.gd index b4354562..47094660 100644 --- a/game/tests/unit/core/save_slot_summary_test.gd +++ b/game/tests/unit/core/save_slot_summary_test.gd @@ -36,7 +36,7 @@ func _write_slot_json(path: String, content: String) -> void: # ① 三槽异值逐槽三项正确+不激活不写内存(sv7) func _test_peek_three_slots_distinct_values() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:174(槽位摘要按槽窥视组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:174 (槽位摘要按槽窥视组) var t := SaveManagerScript.new() t.slots.attach_slot_template(TPL) for i in range(1, 4): @@ -58,7 +58,7 @@ func _test_peek_three_slots_distinct_values() -> void: # ② 空槽零值合法态+不可读三态显式标记(sv7/契约 9) func _test_peek_empty_and_unreadable_states() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:174(坏槽三态组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:174 (坏槽三态组) var t := SaveManagerScript.new() t.slots.attach_slot_template(TPL) DirAccess.remove_absolute(TPL % 3) # 清①段残留——空槽夹具 @@ -79,7 +79,7 @@ func _test_peek_empty_and_unreadable_states() -> void: # ③ 窥视零副作用:字节+mtime 双比对不变+零 .corrupt.bak 改名(sv8——真实入口冒烟段同判据) func _test_peek_zero_side_effect() -> void: -# oracle: design/gdd/systems/表现与支撑/存档序列化.md:174(窥视零副作用组) +# oracle: design/gdd/systems/表现与支撑/存档序列化.md:174 (窥视零副作用组) var t := SaveManagerScript.new() t.slots.attach_slot_template(TPL) _write_slot_json(TPL % 1, "corrupt bytes {{{{") diff --git a/game/tests/unit/core/settle_segments_test.gd b/game/tests/unit/core/settle_segments_test.gd index edebe932..d209504c 100644 --- a/game/tests/unit/core/settle_segments_test.gd +++ b/game/tests/unit/core/settle_segments_test.gd @@ -9,7 +9,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: -# oracle: design/gdd/systems/战斗循环/战斗结算.md:362(结算五段 Segment——五段全序组) +# oracle: design/gdd/systems/战斗循环/战斗结算.md:362 (结算五段 Segment——五段全序组) var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): print("[settle_segments_test] FAIL — 数值表加载失败") diff --git a/game/tests/unit/core/treasure_effects_test.gd b/game/tests/unit/core/treasure_effects_test.gd index 16e184c7..3a989daa 100644 --- a/game/tests/unit/core/treasure_effects_test.gd +++ b/game/tests/unit/core/treasure_effects_test.gd @@ -10,7 +10,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: -# oracle: design/gdd/systems/跨局循环/秘宝.md:246(秘宝 12 件逐件行为——效果行为组) +# oracle: design/gdd/systems/跨局循环/秘宝.md:246 (秘宝 12 件逐件行为——效果行为组) var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): Kit.check_quiet(false, "数值表加载") diff --git a/game/tests/unit/core/treasure_items_test.gd b/game/tests/unit/core/treasure_items_test.gd index c46ee17f..f998c777 100644 --- a/game/tests/unit/core/treasure_items_test.gd +++ b/game/tests/unit/core/treasure_items_test.gd @@ -53,7 +53,7 @@ func _all_revealed(_c: Vector2i) -> bool: func _init() -> void: -# oracle: design/gdd/systems/跨局循环/秘宝.md:246(秘宝结构冻结与护栏校验——结构组) +# oracle: design/gdd/systems/跨局循环/秘宝.md:246 (秘宝结构冻结与护栏校验——结构组) # ① 授予归因+受理序+Used 不可逆 var inv = _new_inv() var r1: Dictionary = inv.add_item("sapper_order", "safe_cell", Vector2i(3, 4), 2) diff --git a/game/tests/unit/core/tree_requires_level_test.gd b/game/tests/unit/core/tree_requires_level_test.gd index 1434ce5a..e3b1a907 100644 --- a/game/tests/unit/core/tree_requires_level_test.gd +++ b/game/tests/unit/core/tree_requires_level_test.gd @@ -7,7 +7,7 @@ extends SceneTree func _init() -> void: -# oracle: design/gdd/systems/跨局循环/天赋树.md:195(等级阈值前置:schema 四拒一过+判定三态+投影两态组) +# oracle: design/gdd/systems/跨局循环/天赋树.md:195 (等级阈值前置:schema 四拒一过+判定三态+投影两态组) var failures := 0 var db = load("res://core/config_db.gd").new() var mt = load("res://data/schemas/meta_tree_table.gd").new() diff --git a/game/tests/unit/core/tree_rules_v11_test.gd b/game/tests/unit/core/tree_rules_v11_test.gd index 834881ef..f737a0d9 100644 --- a/game/tests/unit/core/tree_rules_v11_test.gd +++ b/game/tests/unit/core/tree_rules_v11_test.gd @@ -12,7 +12,7 @@ extends SceneTree func _init() -> void: -# oracle: design/gdd/systems/跨局循环/天赋树.md:194(结构封闭:六键合成行闭集校验组) +# oracle: design/gdd/systems/跨局循环/天赋树.md:194 (结构封闭:六键合成行闭集校验组) var eng = load("res://core/effect_engine.gd") var tree_tbl = load("res://data/schemas/meta_tree_table.gd") var db = load("res://core/config_db.gd").new() @@ -89,7 +89,7 @@ func _init() -> void: # ---- 规则键参数域校验(架构整改批 R1——六键参数字典):正例全过/缺参数拒/多参数拒/越域拒/非字典拒 ---- func _test_rule_key_params(eng, tree_tbl, db) -> Array: -# oracle: design/gdd/systems/跨局循环/天赋树.md:194(规则键参数字典——参数名/取值域合规组) +# oracle: design/gdd/systems/跨局循环/天赋树.md:194 (规则键参数字典——参数名/取值域合规组) var errs: Array = [] var params_tbl: Dictionary = tree_tbl.RULE_KEY_PARAMS # 正例:meta_tree.tres 现行 Fork 行逐键过 validate(加载期已验——此处显式复核) diff --git a/game/tests/unit/data_config/table_structure_guard_test.gd b/game/tests/unit/data_config/table_structure_guard_test.gd index e52a6cbf..91c09323 100644 --- a/game/tests/unit/data_config/table_structure_guard_test.gd +++ b/game/tests/unit/data_config/table_structure_guard_test.gd @@ -576,6 +576,7 @@ func _conversion_row_of(rows: Array, attr: String) -> Dictionary: # ---- V7 节点图三新键域校验(架构整改——缺新键行拒/width_max 越域拒/两 pct 越域拒/表值全过)---- func _test_level_gen_new_fields() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var tbl = _db.run.level_gen_params var mk := func(mod: Dictionary) -> Dictionary: var row := {"level_index": 1, "layers": 6, "branch_density": 0.3, "battle_ratio": 0.5, "reward_ratio": 0.2, @@ -612,6 +613,7 @@ func _test_level_gen_new_fields() -> void: # ---- 变异表头域校验 / feat cap 必填(架构整改——丁案三件的数据面守卫)---- func _test_variation_header_domains() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var inst = load("res://data/schemas/variation_table.gd").new() inst.percent_of_cells = 5 inst.per_level_bonus = 0 @@ -629,6 +631,7 @@ func _test_variation_header_domains() -> void: func _test_feat_cap_required() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var inst = load("res://data/schemas/feat_table.gd").new() # 生产表全行 cap 在场(加载期已验——此处显式复核 37 行) var all_cap := true diff --git a/game/tests/unit/example_test.gd b/game/tests/unit/example_test.gd index e5412e1a..0dd7c944 100644 --- a/game/tests/unit/example_test.gd +++ b/game/tests/unit/example_test.gd @@ -10,7 +10,7 @@ extends SceneTree const Kit := preload("res://tests/unit/test_kit.gd") # T6 收口:check/汇总退出样板单点 func _init() -> void: -# oracle: design/engineering/test-conventions.md:37(套件协议模板——执行载体与退出码范例组) +# oracle: design/engineering/test-conventions.md:37 (套件协议模板——执行载体与退出码范例组) Kit.check("headless SceneTree 协议可用(quit(code) 通道)", _test_headless_protocol()) Kit.check("命名规范可执行:test_[scenario]_[expected]", _test_naming_convention_followed()) quit(Kit.finish("example_test")) diff --git a/game/tests/unit/presentation/battle_narrator_test.gd b/game/tests/unit/presentation/battle_narrator_test.gd index a5153d9c..f037d1ac 100644 --- a/game/tests/unit/presentation/battle_narrator_test.gd +++ b/game/tests/unit/presentation/battle_narrator_test.gd @@ -18,7 +18,7 @@ class _BossRunner: func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260(战斗叙述宿主——装载组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260 (战斗叙述宿主——装载组) _test_numeric_lines_carry_values() _test_end_text_differs_by_result() _test_phase_text_nonempty() @@ -29,7 +29,7 @@ func _init() -> void: func _test_numeric_lines_carry_values() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272(结算行数值带入组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272 (结算行数值带入组) var rest: String = NarratorScript.rest_line(12, 30, 40) Kit.check("休整叙述带入回复量与当前血量(实际「%s」)" % rest, rest.contains("12") and rest.contains("30") and rest.contains("40")) @@ -40,7 +40,7 @@ func _test_numeric_lines_carry_values() -> void: func _test_end_text_differs_by_result() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272(胜负互异文案组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272 (胜负互异文案组) # 关卡收束(level_end=true)恒为「关卡完成!」——单场胜负文案只在非收束态出现 var level: String = NarratorScript.battle_end_text("lose", true) Kit.check("关卡收束态恒为「关卡完成!」(实际「%s」)" % level, level == "关卡完成!") @@ -53,7 +53,7 @@ func _test_end_text_differs_by_result() -> void: func _test_phase_text_nonempty() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272(阶段行非空组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272 (阶段行非空组) var t: String = NarratorScript.phase_text(1, "", false, false, "") Kit.check("相位叙述非空(实际「%s」)" % t, t != "") var boss: String = NarratorScript.phase_text(2, "", false, true, "灰矮人石君王") @@ -63,7 +63,7 @@ func _test_phase_text_nonempty() -> void: # 叙述寻址按行类取 Boss 行集(S 清单 S15 换代):Boss 节点名必须来自 (关卡, boss, 带) 行集, # 不能落到同深度的战斗行集——期望名由表行集首行读出,不写死字面量。 func _test_boss_name_uses_boss_rowset() -> void: -# oracle: design/gdd/systems/战斗循环/敌人系统.md:295(Boss 名读行集组) +# oracle: design/gdd/systems/战斗循环/敌人系统.md:295 (Boss 名读行集组) var db = load("res://core/config_db.gd").new() var loaded: bool = db.load_tables("res://data/tables", false) Kit.check_quiet(loaded, "叙述寻址用例:数值表加载成功") @@ -92,7 +92,7 @@ func _test_boss_name_uses_boss_rowset() -> void: # 关卡完成停点文案族措辞钉子(口径换代批):回血行/满血合法态/渠道句/摘要关数行—— # 旧措辞退役后玩家可见面由本组断言钉在新措辞上(撤销证明:回退 battle_narrator 对应行→断言红→复原复绿) func _test_level_clear_wording() -> void: -# oracle: design/gdd/ux/level-clear.md:11(关卡结算屏文案组) +# oracle: design/gdd/ux/level-clear.md:11 (关卡结算屏文案组) var healed: String = NarratorScript.curio_pick_header({"level_index": 1, "heal_gained": 5, "hp_before": 10, "hp_after": 15}) Kit.check("关卡完成回血行带入回血量与生命区间(实际「%s」)〔口径换代 V1〕" % healed, healed.contains("关卡完成回血 +5(生命 10 → 15)")) @@ -112,6 +112,7 @@ func _test_level_clear_wording() -> void: # 真实入口=呈现状态快照函数 presentation_snapshot:A 有削弱 B 无 → 两卡投影各现各的(零共享引用) func _test_snapshot_effects_per_unit() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var db = load("res://core/config_db.gd").new() Kit.check("V8 前置:表加载零 error", db.load_tables("res://data/tables", true) and db.diagnostics_count("error") == 0) var rng = load("res://core/rng_service.gd").new() diff --git a/game/tests/unit/presentation/camp_scene_layout_test.gd b/game/tests/unit/presentation/camp_scene_layout_test.gd index 9da306de..a4a74b07 100644 --- a/game/tests/unit/presentation/camp_scene_layout_test.gd +++ b/game/tests/unit/presentation/camp_scene_layout_test.gd @@ -10,12 +10,12 @@ const _EXPECTED_KEYS: Array[StringName] = [&"gate", &"forge", &"dummy", &"chest" func _initialize() -> void: -# oracle: design/gdd/ux/camp.md:29(营地场景布局数据件——纵深与地平线组) +# oracle: design/gdd/ux/camp.md:29 (营地场景布局数据件——纵深与地平线组) call_deferred("_test_layout_hotspot_geometry") func _test_layout_hotspot_geometry() -> void: -# oracle: design/gdd/ux/camp.md:16(七物件命中区几何红线组) +# oracle: design/gdd/ux/camp.md:16 (七物件命中区几何红线组) var table: CampSceneLayoutTable = load("res://data/tables/camp_scene_layout.tres") Kit.check("V14 布局表加载且 schema 类在位〔营地图批 V14〕", table is CampSceneLayoutTable and table != null) if table == null: diff --git a/game/tests/unit/presentation/forge_workbench_test.gd b/game/tests/unit/presentation/forge_workbench_test.gd index a4f94893..907ec41b 100644 --- a/game/tests/unit/presentation/forge_workbench_test.gd +++ b/game/tests/unit/presentation/forge_workbench_test.gd @@ -10,7 +10,7 @@ const _TEST_SAVE := "user://test_forge_workbench.json" func _initialize() -> void: -# oracle: design/gdd/systems/跨局循环/锻造工坊.md:219(工作间两区六路线——装载组) +# oracle: design/gdd/systems/跨局循环/锻造工坊.md:219 (工作间两区六路线——装载组) call_deferred("_run") @@ -22,7 +22,7 @@ func _row_by_id(ov) -> Dictionary: func _run() -> void: -# oracle: design/gdd/systems/跨局循环/锻造工坊.md:219(六路线 UI 直验组) +# oracle: design/gdd/systems/跨局循环/锻造工坊.md:219 (六路线 UI 直验组) var db = load("res://core/config_db.gd").new() var load_ok: bool = db.load_tables("res://data/tables", true) if not load_ok: diff --git a/game/tests/unit/presentation/hud_presenter_test.gd b/game/tests/unit/presentation/hud_presenter_test.gd index 5aaba4c7..2c85c0d1 100644 --- a/game/tests/unit/presentation/hud_presenter_test.gd +++ b/game/tests/unit/presentation/hud_presenter_test.gd @@ -9,7 +9,7 @@ const HudScript := preload("res://presentation/hud_presenter.gd") func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260(HUD 投影宿主——装载组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260 (HUD 投影宿主——装载组) _test_accepted_text() _test_reject_text_by_reason() _test_unknown_reason_fallback() @@ -17,13 +17,13 @@ func _init() -> void: func _test_accepted_text() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:212(受理反馈呈现组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:212 (受理反馈呈现组) var t: String = HudScript.outcome_text({"accepted": true}) Kit.check("受理态文案固定为「执行完成。」(实际「%s」)" % t, t == "执行完成。") func _test_reject_text_by_reason() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:212(拒绝三源可辨文案组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:212 (拒绝三源可辨文案组) var cases := { "not_adjacent": "不能执行:目标与小人不相邻", "target_revealed": "不能执行:目标已开", @@ -42,7 +42,7 @@ func _test_reject_text_by_reason() -> void: func _test_unknown_reason_fallback() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:212(未知兜底文案组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:212 (未知兜底文案组) var t: String = HudScript.outcome_text({"accepted": false, "reject_reason": "brand_new_reason"}) Kit.check("未知拒绝原因兜底为「动作被拒。」而非空串(实际「%s」)" % t, t == "动作被拒。") var sub: String = HudScript.outcome_text({ diff --git a/game/tests/unit/presentation/level_map_info_fog_test.gd b/game/tests/unit/presentation/level_map_info_fog_test.gd index b0f42d62..d103f20b 100644 --- a/game/tests/unit/presentation/level_map_info_fog_test.gd +++ b/game/tests/unit/presentation/level_map_info_fog_test.gd @@ -11,12 +11,12 @@ const ScreenScript := preload("res://presentation/views/level_map_screen.gd") func _initialize() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178(信息迷雾呈现宿主——装载组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178 (信息迷雾呈现宿主——装载组) call_deferred("_run") func _run() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178(迷雾显隐宿主组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178 (迷雾显隐宿主组) var db = load("res://core/config_db.gd").new() var loaded: bool = db.load_tables("res://data/tables", false) Kit.check_quiet(loaded, "迷雾呈现用例:数值表加载成功") @@ -48,7 +48,7 @@ func _runner(db, nodes: Array, candidates: Array, n: int = 2): # ---- ① 范围外只见结构:雾下节点类型图标与文字均不绘制〔fv2〕---- func _test_fog_hides_type() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178(雾下类型隐藏组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178 (雾下类型隐藏组) var node := {"id": 3, "type": "battle", "depth": 3, "next": []} var shown: Dictionary = ScreenScript.node_display(node, 2, [2], false, false) Kit.check("可见集内节点:图标/类型文字均绘制〔fv2〕", @@ -62,7 +62,7 @@ func _test_fog_hides_type() -> void: # ---- ② Boss/终点不入雾+多终点标记〔fv3〕---- func _test_boss_exempt_and_multi_boss() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178(Boss 描边豁免与多 Boss 组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178 (Boss 描边豁免与多 Boss 组) var type_vis: Array = [1, 7, 9] # 双 Boss 图:7/9 均在可见集 var boss_a: Dictionary = ScreenScript.node_display({"id": 7, "type": "boss", "depth": 7, "next": []}, 7, type_vis, false, false) var boss_b: Dictionary = ScreenScript.node_display({"id": 9, "type": "boss", "depth": 9, "next": []}, 9, type_vis, false, false) @@ -80,7 +80,7 @@ func _test_boss_exempt_and_multi_boss() -> void: # ---- ③ 节点内详情图上从不显示〔fv5〕---- func _test_details_never_shown() -> void: -# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178(详情零显示组) +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178 (详情零显示组) var plain := {"id": 3, "type": "battle", "depth": 3, "next": [4]} var loaded := {"id": 3, "type": "battle", "depth": 3, "next": [4], "enemy_id": "goblin_secret", "reward_id": "reward_secret"} var a: Dictionary = ScreenScript.node_display(plain, 3, [3], false, true) @@ -97,6 +97,7 @@ func _test_details_never_shown() -> void: # ---- ④ label_text 三态文案〔fv2〕---- func _test_label_three_states() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var node := {"id": 3, "type": "battle", "depth": 3, "next": [4]} Kit.check("当前位文案=「当前位置」〔fv2〕", String(ScreenScript.node_display(node, 3, [3], true, false)["label_text"]) == "当前位置") @@ -149,6 +150,7 @@ func _big_graph_nodes() -> Array: func _test_big_graph_fit(db) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var nodes := _big_graph_nodes() var entry: Dictionary = nodes[0] var runner = _runner(db, nodes, [nodes[1]]) @@ -202,6 +204,7 @@ func _test_big_graph_fit(db) -> void: # 命中读数 = is_same 同实例判别(重算必产新字典、命中返回缓存原实例)——零生产计数器。 func _test_layout_cache(db) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var nodes := _big_graph_nodes() var runner = _runner(db, nodes, [nodes[1]]) var screen = ScreenScript.new() diff --git a/game/tests/unit/presentation/modal_flow_test.gd b/game/tests/unit/presentation/modal_flow_test.gd index 892eaa4e..6e2db94e 100644 --- a/game/tests/unit/presentation/modal_flow_test.gd +++ b/game/tests/unit/presentation/modal_flow_test.gd @@ -11,7 +11,7 @@ const ModalStackScript := preload("res://presentation/modal_stack.gd") func _init() -> void: -# oracle: design/engineering/code-conventions.md:54(模态编排纯逻辑——层级与输入锁组) +# oracle: design/engineering/code-conventions.md:54 (模态编排纯逻辑——层级与输入锁组) # 哑层与桩 Callable(纯逻辑类零场景前提的证明面) var start := Control.new() var inter := Control.new() diff --git a/game/tests/unit/presentation/pacing_queue_test.gd b/game/tests/unit/presentation/pacing_queue_test.gd index 5992ea18..0e16413e 100644 --- a/game/tests/unit/presentation/pacing_queue_test.gd +++ b/game/tests/unit/presentation/pacing_queue_test.gd @@ -37,12 +37,13 @@ class FakeFx extends SettlementFxView: func check(cond: bool, msg: String) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) if not cond: _problems.append(msg) func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272(排播节奏——排空零分叉/零丢行/延迟双态组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272 (排播节奏——排空零分叉/零丢行/延迟双态组) var main: Node = load("res://presentation/main.tscn").instantiate() root.add_child(main) await process_frame @@ -156,6 +157,7 @@ func _count_row(row: Dictionary, arr: Array) -> void: func _finish() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) for p in ["user://test_pacing_queue_save.json", "user://test_pacing_queue_save.json.tmp"]: if FileAccess.file_exists(p): DirAccess.remove_absolute(p) diff --git a/game/tests/unit/presentation/player_copy_sweep_test.gd b/game/tests/unit/presentation/player_copy_sweep_test.gd index 0da52ecc..de41e562 100644 --- a/game/tests/unit/presentation/player_copy_sweep_test.gd +++ b/game/tests/unit/presentation/player_copy_sweep_test.gd @@ -23,7 +23,7 @@ var _db func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:281(玩家面文案清扫宿主——装载组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:281 (玩家面文案清扫宿主——装载组) _db = ConfigDBScript.new() var load_ok: bool = _db.load_tables("res://data/tables", true) if not load_ok: @@ -43,7 +43,7 @@ func _init() -> void: # ① C 区两段头(u1/u2——直建 hero 面板,adventure_feats_test ⑦c 族同构) func _sweep_hero_panel() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:274(英雄面板文案组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:274 (英雄面板文案组) var panel = load("res://presentation/views/hero_info_panel_view.gd").new(_db.presentation.battle_layout) var feat_head := _first_label(panel._feat_section) var curio_head := _first_label(panel._curio_section) @@ -55,7 +55,7 @@ func _sweep_hero_panel() -> void: # ②③ 奖励节点头部+专长卡兜底(u3/u11——静态直调) func _sweep_narrator() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272(叙述文案组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272 (叙述文案组) var narrator = load("res://presentation/battle_narrator.gd") var head := String(narrator.node_curio_header()) Kit.check("奖励点头部含「冒险牌库」(u3 机制事实①同库)〔wa4〕", head.contains("冒险牌库")) @@ -68,7 +68,7 @@ func _sweep_narrator() -> void: # ④ 图例封印行(u4——直建 LegendOverlay 读 ENTRIES 常量) func _sweep_legend() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:267(图例文案组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:267 (图例文案组) load("res://presentation/views/legend_overlay.gd").new() # 直建(_init(rap_cost) 现签名) var seal_row: Array = [] for e in load("res://presentation/views/legend_overlay.gd").ENTRIES: @@ -84,7 +84,7 @@ func _sweep_legend() -> void: # ⑤⑥ 来源名双源(u5/u6——状态槽消费半+表值 ConfigDB 真装载+battle_log 行消费半) func _sweep_source_names() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:274(来源名读表组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:274 (来源名读表组) var row_view = load("res://presentation/views/status_slot_row.gd").new() row_view.set_effects([{"effect_id": "alert", "source_class": "mine_hit", "display_name": "危险格受击", "remaining_settlements": 2, "round_index": 1}]) @@ -110,7 +110,7 @@ func _sweep_source_names() -> void: # ⑦⑧ 已开危险格字形族(u7/u8/u9——BoardView rebuild 真实刷新路径+源 token 扫描) func _sweep_board_glyph() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:264(危险格字形组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:264 (危险格字形组) var board_generator = load("res://core/board_generator.gd").new() var b = board_generator.generate(1, 0, _mk_stream("board_gen", 4242), _db) var ae = load("res://core/action_economy.gd").new(_db) @@ -149,6 +149,7 @@ func _sweep_board_glyph() -> void: # ⑧⑩ 源 token 扫描(注释剥离=行首 # 判——契约 2 保留面不入域) func _sweep_token_scans() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var board_src := FileAccess.get_file_as_string("res://presentation/views/board_view.gd") Kit.check("board_view.gd 源零 \"雷\" 字面量(u7/u8/u9 哨兵族统一钉住)〔wa8〕", board_src.count("\"雷\"") == 0) @@ -166,7 +167,7 @@ func _sweep_token_scans() -> void: # 刷新两 toast 文案零数字字面量(架构整改 R4——格式串零数字、插值位与表字段一一对应; # 静态判据+评审注记观测面局限:真机文案随表值由实机目检兜——T10 清单两项) func _sweep_refresh_toast_no_literals() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260(刷新提示读表拼接——零字面量组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260 (刷新提示读表拼接——零字面量组) var main_src := FileAccess.get_file_as_string("res://presentation/main.gd") var rap_toast := "" var cap_toast := "" diff --git a/game/tests/unit/presentation/presentation_encapsulation_sweep_test.gd b/game/tests/unit/presentation/presentation_encapsulation_sweep_test.gd index 461752d3..caee31ea 100644 --- a/game/tests/unit/presentation/presentation_encapsulation_sweep_test.gd +++ b/game/tests/unit/presentation/presentation_encapsulation_sweep_test.gd @@ -33,7 +33,7 @@ const A1_FILES := { func _init() -> void: -# oracle: design/engineering/code-conventions.md:41(presentation 封装——四族零命中扫描组) +# oracle: design/engineering/code-conventions.md:41 (presentation 封装——四族零命中扫描组) _sweep_a1_data_classes() _sweep_a2_subparts() _sweep_b_combo_root() @@ -43,7 +43,7 @@ func _init() -> void: # 源文件读取+非空前置(返 "" 即已判红——调用侧跳过后续正则断言) func _src(path: String) -> String: -# oracle: design/engineering/code-conventions.md:41(源码采样组) +# oracle: design/engineering/code-conventions.md:41 (源码采样组) var src := FileAccess.get_file_as_string(path) Kit.check("扫描面非空前置:%s" % path, src.length() > 0) return src @@ -51,21 +51,21 @@ func _src(path: String) -> String: # 正则零命中断言(-pattern 意图写入断言文案——可 grep 定位;suffix 区分族组) func _zero(pattern: String, src: String, label: String, suffix: String = "pres封装 V1") -> void: -# oracle: design/engineering/code-conventions.md:41(零命中扫描组) +# oracle: design/engineering/code-conventions.md:41 (零命中扫描组) var re := RegEx.create_from_string(pattern) Kit.check("%s:%s 零命中〔%s〕" % [label, pattern, suffix], re.search(src) == null) # 正锚在案断言(正则命中 ≥1——新公开面/新形态在用;suffix 区分族组) func _anchor(pattern: String, src: String, label: String, suffix: String = "pres封装 V1") -> void: -# oracle: design/engineering/code-conventions.md:41(正锚存在组) +# oracle: design/engineering/code-conventions.md:41 (正锚存在组) var re := RegEx.create_from_string(pattern) Kit.check("%s:%s 正锚在案〔%s〕" % [label, pattern, suffix], re.search(src) != null) # ② V2 A2 拆件子件(行为归位子件公开方法、读走公开读法、身份构造交付) func _sweep_a2_subparts() -> void: -# oracle: design/engineering/code-conventions.md:41(A2 子件封装扫描组) +# oracle: design/engineering/code-conventions.md:41 (A2 子件封装扫描组) var body := _src("res://presentation/views/standee_body.gd") if body.length() > 0: _zero("\\bst\\._|\\bmo\\._", body, "子件私取模式零命中(standee_body)", "pres封装 V2") @@ -82,7 +82,7 @@ func _sweep_a2_subparts() -> void: # ③ V3 B 组合根交接面(main+五分文件——成对单行转发梯换代为公开入口+Callable 束) func _sweep_b_combo_root() -> void: -# oracle: design/engineering/code-conventions.md:41(组合根束封装扫描组) +# oracle: design/engineering/code-conventions.md:41 (组合根束封装扫描组) var b_files := { "res://presentation/main.gd": false, "res://presentation/main_ui_build.gd": true, @@ -117,6 +117,7 @@ func _sweep_b_combo_root() -> void: # ④ V4 C 杂项(UiKit 私有工厂公开化+cell_mark 构造交付) func _sweep_c_misc() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var offenders: PackedStringArray = [] var scanned := 0 _walk_gd_for("res://", "UiKit\\._[a-zA-Z]", "res://presentation/views/ui_kit.gd", offenders) @@ -154,6 +155,7 @@ func _walk_gd_for(dir_path: String, pattern: String, exclude: String, offenders: # ① V1 A1 三内部数据类(字段公开化——宿主直读写内类私有字段清零) func _sweep_a1_data_classes() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) for path in A1_FILES: var spec: Dictionary = A1_FILES[path] var src := _src(path) diff --git a/game/tests/unit/presentation/reward_overlay_test.gd b/game/tests/unit/presentation/reward_overlay_test.gd index f6323e36..51937212 100644 --- a/game/tests/unit/presentation/reward_overlay_test.gd +++ b/game/tests/unit/presentation/reward_overlay_test.gd @@ -9,7 +9,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") # 断言 + 失败即停(原直写 print FAIL + quit(1) + return 样板单点化——早退语义逐位保持) func _req(desc: String, ok: bool) -> bool: -# oracle: design/gdd/ux/node-reward.md:9(奖励覆盖层直验——需求包装组) +# oracle: design/gdd/ux/node-reward.md:9 (奖励覆盖层直验——需求包装组) Kit.check(desc, ok) if not ok: quit(1) @@ -17,11 +17,11 @@ func _req(desc: String, ok: bool) -> bool: return true func _initialize() -> void: -# oracle: design/gdd/ux/node-reward.md:9(奖励节点装载组) +# oracle: design/gdd/ux/node-reward.md:9 (奖励节点装载组) call_deferred("_run") func _run() -> void: -# oracle: design/gdd/ux/node-reward.md:9(奖励三选一呈现组) +# oracle: design/gdd/ux/node-reward.md:9 (奖励三选一呈现组) var ov = load("res://presentation/views/curio_pick_overlay.gd").new() root.add_child(ov) var picked := [] diff --git a/game/tests/unit/presentation/seal_mark_params_test.gd b/game/tests/unit/presentation/seal_mark_params_test.gd index f13d220b..6e7e4bb5 100644 --- a/game/tests/unit/presentation/seal_mark_params_test.gd +++ b/game/tests/unit/presentation/seal_mark_params_test.gd @@ -10,7 +10,7 @@ const CELL_UNIT := preload("res://presentation/views/board_cell_unit.gd") func _init() -> void: -# oracle: design/gdd/ux/battle.md:128(封印印记参数宿主——装载组) +# oracle: design/gdd/ux/battle.md:128 (封印印记参数宿主——装载组) _test_param_values() _test_shader_uniforms() _test_fog_gate() @@ -19,7 +19,7 @@ func _init() -> void: # R1–R3/R7 前置:五常量取值逐项相等(art-bible §8.2 定值) func _test_param_values() -> void: -# oracle: design/gdd/ux/battle.md:128(环径与法阵定值组) +# oracle: design/gdd/ux/battle.md:128 (环径与法阵定值组) Kit.check("SEAL_RING_FRAC = 0.82〔seal批 V1〕", UiKit.SEAL_RING_FRAC == 0.82) Kit.check("SEAL_WALL_FRAC = 0.11〔seal批 V2〕", UiKit.SEAL_WALL_FRAC == 0.11) Kit.check("SEAL_ARM_FRAC = 0.156〔seal批 V2〕", UiKit.SEAL_ARM_FRAC == 0.156) @@ -29,7 +29,7 @@ func _test_param_values() -> void: # R1–R3/R7:着色器存在+七个 uniform 名在文(参数注入面契约) func _test_shader_uniforms() -> void: -# oracle: design/gdd/ux/battle.md:128(着色器参数化绘制组) +# oracle: design/gdd/ux/battle.md:128 (着色器参数化绘制组) var src := FileAccess.get_file_as_string(SEAL_SHADER) Kit.check("着色器文件存在且非空:%s〔seal批 V1〕" % SEAL_SHADER, src.length() > 0) if src.length() == 0: @@ -43,7 +43,7 @@ func _test_shader_uniforms() -> void: # R4 迷雾门控:seal_on × fog_state → 封印子件可见性(内部字段直查=受控例外——子件可见性无公开可观测面, # 卡面 R4 断言即 prescribe 子件 visible 直查;对照表该行注记理由) func _test_fog_gate() -> void: -# oracle: design/gdd/ux/battle.md:128(迷雾联动门控组) +# oracle: design/gdd/ux/battle.md:128 (迷雾联动门控组) var u: Node2D = CELL_UNIT.new() u.seal_on = true Kit.check("seal_on 即挂封印子件〔seal批 V4〕", u._seal_layer != null) diff --git a/game/tests/unit/presentation/settings_store_test.gd b/game/tests/unit/presentation/settings_store_test.gd index 4a4710f5..67aa6df4 100644 --- a/game/tests/unit/presentation/settings_store_test.gd +++ b/game/tests/unit/presentation/settings_store_test.gd @@ -12,7 +12,7 @@ const ISO_PATH := "user://settings_store_unit_test.cfg" # 隔离注路径( func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/设置与本地化.md:4(设置存储宿主——装载组) +# oracle: design/gdd/systems/表现与支撑/设置与本地化.md:4 (设置存储宿主——装载组) _test_settings_roundtrip() _test_settings_default() _test_settings_apply_chain() @@ -27,7 +27,7 @@ func _cleanup() -> void: # ---- 持久化回读(写 true→存→新实例回读 true;节/键 motion/reduced)---- func _test_settings_roundtrip() -> void: -# oracle: design/gdd/systems/表现与支撑/设置与本地化.md:4(设置写读往返组) +# oracle: design/gdd/systems/表现与支撑/设置与本地化.md:4 (设置写读往返组) var w = StoreScript.new(ISO_PATH) w.reduced_motion = true Kit.check("前置:save_settings 落盘成功", w.save_settings()) @@ -44,7 +44,7 @@ func _test_settings_roundtrip() -> void: # ---- 缺省值(无文件缺省 false)---- func _test_settings_default() -> void: -# oracle: design/gdd/systems/表现与支撑/设置与本地化.md:4(出厂默认组) +# oracle: design/gdd/systems/表现与支撑/设置与本地化.md:4 (出厂默认组) var absent_path := "user://settings_store_unit_absent_%d.cfg" % (Time.get_ticks_msec()) DirAccess.remove_absolute(ProjectSettings.globalize_path(absent_path)) # 确保无文件 var d = StoreScript.new(absent_path) @@ -55,7 +55,7 @@ func _test_settings_default() -> void: # ---- 引擎档应用链(reduced→apply()→UiKit.motion_scale==0.5,false→1.0;测毕还原静态初值)---- func _test_settings_apply_chain() -> void: -# oracle: design/gdd/systems/表现与支撑/设置与本地化.md:4(应用链组) +# oracle: design/gdd/systems/表现与支撑/设置与本地化.md:4 (应用链组) var saved_scale: float = UiKit.motion_scale # 静态初值留底——测毕还原 var a = StoreScript.new(ISO_PATH) a.reduced_motion = true diff --git a/game/tests/unit/presentation/stage_background_test.gd b/game/tests/unit/presentation/stage_background_test.gd index 4958b7c1..2a473af0 100644 --- a/game/tests/unit/presentation/stage_background_test.gd +++ b/game/tests/unit/presentation/stage_background_test.gd @@ -26,12 +26,12 @@ class AllMissingStage extends BattleStageView: func _initialize() -> void: -# oracle: design/gdd/ux/battle.md:122(舞台背景宿主——装载组) +# oracle: design/gdd/ux/battle.md:122 (舞台背景宿主——装载组) call_deferred("_run") func _run() -> void: -# oracle: design/gdd/ux/battle.md:122(B 区背景宿主组) +# oracle: design/gdd/ux/battle.md:122 (B 区背景宿主组) _test_layout_ground_field() await _test_background_selection() await _test_background_fallback() @@ -42,7 +42,7 @@ func _run() -> void: # ---- V1 ground_h 字段与校验(表值/默认表 validate 空/三态拒绝族) ---- func _test_layout_ground_field() -> void: -# oracle: design/gdd/ux/battle.md:122(连续地面层组) +# oracle: design/gdd/ux/battle.md:122 (连续地面层组) var layout = load("res://data/tables/battle_layout.tres") Kit.check("布局表 ground_h = 100 且默认表 validate 为空〔舞台背景 V1〕", int(layout.ground_h) == 100 and layout.validate().is_empty()) @@ -75,7 +75,7 @@ func _make_stage() -> Node: # ---- V2 背景按 board_type 选图(直建默认 dungeon + 三值路径逐值对应 + 层序在世界之下) ---- func _test_background_selection() -> void: -# oracle: design/gdd/ux/battle.md:122(三关变体选图组) +# oracle: design/gdd/ux/battle.md:122 (三关变体选图组) var layout = load("res://data/tables/battle_layout.tres") var stage: Node = _make_stage() await process_frame @@ -104,7 +104,7 @@ func _test_background_selection() -> void: # ---- V3 缺图回退(目标缺→dungeon;全缺→平色兜底不崩不刷产品日志) ---- func _test_background_fallback() -> void: -# oracle: design/gdd/ux/battle.md:122(缺位回退组) +# oracle: design/gdd/ux/battle.md:122 (缺位回退组) var s1: Node = MissingUnderdarkStage.new(null, load("res://data/tables/battle_layout.tres")) root.add_child(s1) await process_frame @@ -128,6 +128,7 @@ func _test_background_fallback() -> void: # ---- V4 连续地面层几何(底贴 B 区底、高读表、全宽、位于背景与世界之间) ---- func _test_ground_layer_geometry() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var layout = load("res://data/tables/battle_layout.tres") var stage: Node = _make_stage() await process_frame @@ -154,6 +155,7 @@ func _test_ground_layer_geometry() -> void: # ---- V5 光柱层与舞台底源常量退役(源码锚 + 常量表 + 菜单斜光带在位) ---- func _test_beams_retired() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var f := FileAccess.open("res://presentation/views/battle_stage_view.gd", FileAccess.READ) var src := f.get_as_text() if f != null else "" Kit.check("舞台源码零光柱残留且平色回退含合并目标 SLOT_BACKDROP〔舞台背景 V5〕", diff --git a/game/tests/unit/presentation/standee_fx_sweep_test.gd b/game/tests/unit/presentation/standee_fx_sweep_test.gd index ad5a9cd3..47a665ae 100644 --- a/game/tests/unit/presentation/standee_fx_sweep_test.gd +++ b/game/tests/unit/presentation/standee_fx_sweep_test.gd @@ -69,7 +69,7 @@ class FakeDB: func _init() -> void: -# oracle: design/gdd/ux/battle.md:154(站桩呈现域缺陷扫掠组) +# oracle: design/gdd/ux/battle.md:154 (站桩呈现域缺陷扫掠组) UiKit.motion_scale = 1.0 # ---- ⑤ 站桩按 id 解析(两口共用同名字敌载体)---- diff --git a/game/tests/unit/presentation/standee_present_values_test.gd b/game/tests/unit/presentation/standee_present_values_test.gd index 35e1e589..0d64a4d5 100644 --- a/game/tests/unit/presentation/standee_present_values_test.gd +++ b/game/tests/unit/presentation/standee_present_values_test.gd @@ -31,7 +31,7 @@ func _read_source(rel_path: String) -> String: func _init() -> void: -# oracle: design/gdd/ux/battle.md:154(站桩呈现定值与素材绑定组) +# oracle: design/gdd/ux/battle.md:154 (站桩呈现定值与素材绑定组) # ---- V5 血条填充 = 危险红 #A8321F(§4.2 语义物件显式落法) ---- Kit.check("血条填充常量 = 危险红 #A8321F〔样张批 V5〕", UiKit.HP_BAR_FILL.to_html(false) == "a8321f") @@ -137,7 +137,7 @@ func _enemy_tex_path(key: String) -> String: func _check_display_tier() -> void: -# oracle: design/gdd/ux/battle.md:154(显示档与分辨率绑定组) +# oracle: design/gdd/ux/battle.md:154 (显示档与分辨率绑定组) # V13/V15 九键逐一:真实入口 StandeeBody → set_data(enemy_id) → set_portrait_texture(真纹理) → portrait_probe for key: String in _DISPLAY_SPEC: var spec: Array = _DISPLAY_SPEC[key] diff --git a/game/tests/unit/presentation/terrain_tile_sets_test.gd b/game/tests/unit/presentation/terrain_tile_sets_test.gd index 706c7155..71519fde 100644 --- a/game/tests/unit/presentation/terrain_tile_sets_test.gd +++ b/game/tests/unit/presentation/terrain_tile_sets_test.gd @@ -13,7 +13,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") # T6 收口:_check/汇 func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260(地形瓦片套宿主——装载组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260 (地形瓦片套宿主——装载组) var board_dir := ProjectSettings.globalize_path("res://assets/art/board/") var probe_path := board_dir.path_join("terrain_wall_center_dungeon.png") if not FileAccess.file_exists(probe_path): @@ -42,7 +42,7 @@ func _init() -> void: # 套完整性:词表每个 board_type 的 16 墙 + 5 地面变体全部在盘(缺位 → BoardView 整批回落 dungeon 的 # 缺位回退断言由 ui_input_probe 覆盖;本断言管「入包完整」面) func _test_set_completeness(board_dir: String, types: Array) -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260(瓦片套完整性组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260 (瓦片套完整性组) var wall_names: Array = TilePaletteScript.TILE_WALL_NAMES var variants: int = int(TilePaletteScript.TILE_FLOOR_VARIANTS) for bt in types: @@ -124,7 +124,7 @@ func _load_stats(board_dir: String, fname: String, top_half: bool) -> Dictionary # (双峰纹理直画不可救——渲染帧取证深墨隐形实证,牌上深墨 12:1);③直画模式的双门槛值照抄 # TilePalette 判据常量(防判据漂移) func _test_digit_ink_modes(board_dir: String, types: Array) -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260(数字墨色模式组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260 (数字墨色模式组) var expect_plate := {"dungeon": false, "underdark": true, "deep_underdark": true} var variants: int = int(TilePaletteScript.TILE_FLOOR_VARIANTS) for bt in types: diff --git a/game/tests/unit/presentation/theme_projection_test.gd b/game/tests/unit/presentation/theme_projection_test.gd index d18f3b48..f5e2bdda 100644 --- a/game/tests/unit/presentation/theme_projection_test.gd +++ b/game/tests/unit/presentation/theme_projection_test.gd @@ -30,7 +30,7 @@ var _rng func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260(呈现投影与主题宿主——装载组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260 (呈现投影与主题宿主——装载组) _db = ConfigDBScript.new() # 表加载失败不中止(承 G2–G5 同款:表损坏的红落在具体断言上) var load_ok: bool = _db.load_tables("res://data/tables", true) @@ -181,7 +181,7 @@ func _meta_new_save(path: String): # ---- 未开格类型微光(作用集恒等/九型归组封闭/零玩法写入)---- func _smoke_type_glow() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:267(未开格类型微光数据面组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:267 (未开格类型微光数据面组) print("--- 未开格类型微光(作用集恒等/九型归组封闭/零玩法写入)---") var board_generator = load("res://core/board_generator.gd").new() var b = board_generator.generate(1, 0, _mk_stream("board_gen", 4242), _db) @@ -383,7 +383,7 @@ func _smoke_type_glow() -> void: # _format_row Invalid access 使结算段中途夭折、界面卡死。行协议变更必须同步呈现层〔战斗结算 §行协议〕, # 本段把现行行形态逐型喂进真实视图:拆行残留与行字段错位在此转红)---- func _smoke_battle_log_view() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272(明细带行协议组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272 (明细带行协议组) print("--- 战斗日志视图行格式化(行协议 9 类呈现层同步闸)---") var view = load("res://presentation/views/battle_log_view.gd").new(_db, _db.presentation.battle_layout) # 敌方行动伤害行(现行形态:baseline 在场、attach 已出协议——修复前此行即 Invalid access) @@ -428,7 +428,7 @@ func _smoke_battle_log_view() -> void: # ---- 开场行后缀尾接协议(迭代36 wc1 静态半——level_open_line 第五参布尔直控尾接,签名零变; # 该函数此前零既有断言,尾接行为由此钉住)---- func _smoke_level_open_line() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272(关卡开启行组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:272 (关卡开启行组) var NarratorScript := load("res://presentation/battle_narrator.gd") Kit.check("开场行 boosted=true 尾接「(含面板加成)」〔wc1〕", String(NarratorScript.level_open_line("第一层", 42, 5, 30, true)).contains("(含面板加成)")) @@ -443,7 +443,7 @@ func _smoke_level_open_line() -> void: # V1 挂载覆盖 / V2 滑轨两段 / V3 预盖件运行时证词 / V4 旧形态零残留 / # V5 回归(本冒烟全绿即回归网)/ V6 中文字体防御(挂主题后 default_font 顶掉 custom_font 也不丢字形) func _smoke_global_theme() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260(全局主题组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260 (全局主题组) print("--- UI 全局主题(main_theme.tres 挂载与词条断言)---") var th := ThemeDB.get_project_theme() Kit.check("V1 项目主题挂载(project.godot gui/theme/custom → main_theme.tres)", th != null) @@ -548,7 +548,7 @@ func _smoke_global_theme() -> void: # ---- 按钮五态矩阵冒烟(四工厂产物逐实例 override 断言;V1/V2)---- func _smoke_button_five_states() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260(按钮五态组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260 (按钮五态组) print("--- UI 按钮五态矩阵(四工厂五态样式盒)---") var uikit_s = load("res://presentation/views/ui_kit.gd") var states := ["normal", "hover", "pressed", "disabled", "focus"] @@ -620,7 +620,7 @@ func _smoke_button_five_states() -> void: # ---- 全局纹理过滤冒烟(工程设置 Nearest+平滑渐变件 LINEAR 白名单;V3)---- func _smoke_texture_filter() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260(纹理过滤白名单组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260 (纹理过滤白名单组) print("--- UI 全局纹理过滤(Nearest+白名单三件)---") var v = ProjectSettings.get_setting("rendering/textures/canvas_textures/default_texture_filter") Kit.check("V3 工程设置 default_texture_filter=0(Nearest,翻转面=立绘/瓦片/九宫格 crisp)", @@ -670,7 +670,7 @@ func _smoke_texture_filter() -> void: # ---- <4.5:1 文字位换墨冒烟(站桩徽标两族亮档+RAP 行深石墨;V4)---- func _smoke_contrast_inks() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:281(对比度墨色锚组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:281 (对比度墨色锚组) print("--- UI 残余 <4.5:1 文字位换墨(V4 对比度锚定)---") var uikit_s = load("res://presentation/views/ui_kit.gd") var stage: Color = uikit_s.SLOT_BACKDROP # 舞台底对比锚改读合并目标(art-bible §4.1 换色合并③——阈值与判据不变) @@ -697,7 +697,7 @@ func _smoke_contrast_inks() -> void: # ---- 元素细节余②③冒烟(BCard 图标槽明度差降档+商店居中+营地四栏等高)---- func _smoke_element_details() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:274(元素细节源码锚组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:274 (元素细节源码锚组) print("--- UI 元素细节余②③(图标槽降档+布局修)---") var uikit_s = load("res://presentation/views/ui_kit.gd") # ②白图标 ≥3:1 图形对比硬约束+降档方向锚定 @@ -720,7 +720,7 @@ func _smoke_element_details() -> void: # ---- 诊断转储钮冒烟(角落钮不在玩家画面+转储入口在调试浮窗;V6)---- func _smoke_diag_button_retired() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260(诊断钮退役契约组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:260 (诊断钮退役契约组) print("--- UI 诊断转储钮退役(V6:玩家画面清零+浮窗可达)---") var main_src: String = FileAccess.get_file_as_string("res://presentation/main.gd") Kit.check("V6 主区无 build_diag_button 调用残留(旧实现同批清理)", @@ -744,7 +744,7 @@ func _smoke_diag_button_retired() -> void: # 断言归 ui_struct_probe 呈现侧,本段只管数据面;跨关解锁概览断言族随面板换代退役—— # 替换判据=sv5 零旧段+八键投影断言(实现报告 §8.3 申报))---- func _status_panel_projection() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:274(状态面板只读投影组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:274 (状态面板只读投影组) print("--- 状态面板·本局信息面板投影一致性(迭代36 卡③——八键快照手拼夹具,同构口径不依赖 runner)---") _meta_smoke_cleanup() # 套件级夹具清场(生涯页 fixture 依赖此前置——旧状态段同款保留) # 夹具(代拍板 4——任意非零可辨值,禁读 data/tables 现值、禁与属性行断言共值致误判掩盖) @@ -805,7 +805,7 @@ func _all_labels(root: Node) -> Array: # 只读性连接巡检与零动效断言归 ui_struct_probe 呈现侧,本段只管数据面+旧档载入显示 # (v5 样档升 v6——完成定义 6「计数域缺省补零、页正常显示」))---- func _career_overlay_projection() -> void: -# oracle: design/gdd/ux/camp.md:45(生涯页只读投影组) +# oracle: design/gdd/ux/camp.md:45 (生涯页只读投影组) print("--- 生涯页·只读投影一致性(隔离档 smoke_meta_career/career_v5)---") var sv = _meta_new_save(_META_SMOKE_PATHS[9]) var mp = load("res://core/meta_progression.gd").new(_db, sv) diff --git a/game/tests/unit/presentation/tune_sim_batch_parity_test.gd b/game/tests/unit/presentation/tune_sim_batch_parity_test.gd index b44b9c6f..5fff1de1 100644 --- a/game/tests/unit/presentation/tune_sim_batch_parity_test.gd +++ b/game/tests/unit/presentation/tune_sim_batch_parity_test.gd @@ -163,6 +163,7 @@ func _run_pair(n: int, frame_idx: Dictionary) -> Dictionary: func _check_n3(r: Dictionary) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var pa: FakePanel = r["pa"] var pb: FakePanel = r["pb"] var da: FakeDriver = r["da"] @@ -195,6 +196,7 @@ func _check_n3(r: Dictionary) -> void: func _check_n0(r: Dictionary) -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var pa: FakePanel = r["pa"] var pb: FakePanel = r["pb"] var da: FakeDriver = r["da"] diff --git a/game/tests/unit/presentation/type_glow_test.gd b/game/tests/unit/presentation/type_glow_test.gd index b4fc4bb7..7a0e9dd5 100644 --- a/game/tests/unit/presentation/type_glow_test.gd +++ b/game/tests/unit/presentation/type_glow_test.gd @@ -46,7 +46,7 @@ const CONST_NAME := { func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:267(微光数据面宿主——装载组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:267 (微光数据面宿主——装载组) _test_grouping_closed() _test_frozen_hue_face() _test_render_params() @@ -57,6 +57,7 @@ func _init() -> void: # ① 归组封闭:九值全域映射+清单外显式失败+禁子串+两带差异锚定 func _test_grouping_closed() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) for t in TYPE_EXPECT: var got: int = UiKitScript.glow_group_for_cell_type(t) Kit.check("九型封闭:%s → 组%d(期望组%d)" % [t, got, int(TYPE_EXPECT[t])], got == int(TYPE_EXPECT[t])) @@ -80,6 +81,7 @@ func _test_grouping_closed() -> void: # ② 冻结色相面:逐组 HSV 对照 art-bible §4.2 冻结值——只准动明度(ΔH≤0.2°/ΔS≤0.01) func _test_frozen_hue_face() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) for g in FROZEN: var f: Color = FROZEN[g] var m: Color = IMPL[g] @@ -98,6 +100,7 @@ func _test_frozen_hue_face() -> void: # ③ 呈现参数锚定(art-bible §4.2 v2 冻结参数) func _test_render_params() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) Kit.check("泛光强度 α = 170/255(v2 呈现参数冻结)", is_equal_approx(UiKitScript.TYPE_GLOW_ALPHA, 170.0 / 255.0)) Kit.check("带宽 = cell÷8(TYPE_GLOW_BAND_FRAC=0.125)", @@ -109,6 +112,7 @@ func _test_render_params() -> void: # ④ 合成空间阶梯:模型域单调 + 相邻组 CR ≥1.20(色弱互辨数据面预判;终审=探针实测) func _test_gamma_ladder() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) # 合成模型(ui_kit 头注登记口径):带内均值 ≈ 0.49×色值 + 0.51×瓦片(BRICK 未开掩尘地砖) var k := 0.49 var tile: Color = UiKitScript.BRICK @@ -135,6 +139,7 @@ func _test_gamma_ladder() -> void: # ⑤ probe API 形状:默认开+空态键集(无板直取——不依赖棋盘装配) func _test_probe_api_shape() -> void: +# oracle: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) var view = BoardViewScript.new() var snap: Dictionary = view.type_glow_probe() Kit.check("probe 键集 = {enabled, cells, errors}", diff --git a/game/tests/unit/presentation/ui_font_asset_test.gd b/game/tests/unit/presentation/ui_font_asset_test.gd index 6e1d7801..d263f554 100644 --- a/game/tests/unit/presentation/ui_font_asset_test.gd +++ b/game/tests/unit/presentation/ui_font_asset_test.gd @@ -11,7 +11,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") # T6 收口:_check/汇 func _init() -> void: -# oracle: design/gdd/systems/表现与支撑/HUD框架.md:281(中文字体随包与字形覆盖组) +# oracle: design/gdd/systems/表现与支撑/HUD框架.md:281 (中文字体随包与字形覆盖组) var path: String = UiKitScript.FONT_UI var f: Font = UiKitScript.load_font(path) Kit.check("随包字体守卫装载非空(res://assets/fonts/ui_font_fusion_pixel_zh_hans.ttf)", f != null) diff --git a/tools/capability_audit.py b/tools/capability_audit.py index 6cb4b237..721336ad 100644 --- a/tools/capability_audit.py +++ b/tools/capability_audit.py @@ -14,9 +14,14 @@ r"""capability_audit.py — 能力清单、覆盖域表与 GDD 纯度机检( tests//probe/)有 `func 方法(`,或该方法名能在 reports/需求卡片*.md 中找到(计划入口同 D 口径);两头都无=红。 F 覆盖域表:systems 每篇一行;状态∈{已覆盖,部分覆盖,未覆盖};非未覆盖行的「能力行」非空且每项都能 对上能力表里的行名;部分/未覆盖行的缺口非空且指待办清单。 + G 判据出处随测注记(test-conventions §8.3):game/tests/** 与 game/probe/** 内每个验证函数 + (函数体含 check(/check_quiet(/_problems.append(/push_error( 判定调用,定义行与 _check( 前缀除外) + 须带 ≥1 条 `# oracle: :<行号> <判据一句>` 注记;指针指向存在的设计文档行且不出 + design/ 全域。扫描面=game/tests/**+game/probe/**(sim/ 不进——测量面直构惯例)。 条件闸行豁免(代表用例含「条件闸」字样)不参与 D/E。 -自检四道(防扫描面空转假绿):系统文档数、能力行数、manifest 套件数、覆盖表行数任一为零 ⇒ exit 2。 +自检五道(防扫描面空转假绿):系统文档数、能力行数、manifest 套件数、覆盖表行数、判据注记扫描面文件数 +任一为零 ⇒ exit 2。 用法: python tools/capability_audit.py # 报告模式(红项只打印,不改退出码) @@ -332,6 +337,67 @@ def check_coverage(cov_tables, names): red(README.relative_to(REPO), 1, "覆盖域表", "%s 未在覆盖域表登记" % doc) +ORACLE_RE = re.compile(r"^#\s*oracle:\s*(\S+\.md):(\d+)\s+\S") +VERDICT_RE = re.compile(r"(?