From ddc352a98532fd832bd347e4096184c6bef4e900 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Fri, 6 Nov 2026 07:15:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E7=A8=8B(=E5=88=A4=E6=8D=AE=E5=87=BA?= =?UTF-8?q?=E5=A4=84=E6=B3=A8=E8=AE=B02/7=C2=B7core):=2034=E5=A5=97?= =?UTF-8?q?=E4=BB=B6135=E5=87=BD=E6=95=B0=E9=80=90=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E6=8C=82#=20oracle=E6=B3=A8=E8=AE=B0=E2=80=94=E2=80=94?= =?UTF-8?q?=E8=A1=8C=E4=B8=BA=E5=A5=97=E4=BB=B6=E9=94=9Aowner=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E9=AA=8C=E6=94=B6=E5=8F=A5(=E5=86=92=E9=99=A9?= =?UTF-8?q?=E7=BB=93=E6=9E=84:283-287/=E5=85=B3=E5=8D=A1=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E5=9C=B0=E5=9B=BE:176-184/=E6=A3=8B=E7=9B=98=E7=94=9F=E6=88=90?= =?UTF-8?q?:221-229/=E6=8E=92=E9=9B=B7=E7=8E=A9=E6=B3=95:228-238/=E8=A1=8C?= =?UTF-8?q?=E5=8A=A8=E7=BB=8F=E6=B5=8E/=E6=88=98=E6=96=97=E7=BB=93?= =?UTF-8?q?=E7=AE=97:362/=E5=9C=B0=E5=9B=BE=E6=88=98=E6=96=97=E8=B5=84?= =?UTF-8?q?=E6=BA=90/=E7=A7=98=E5=AE=9D/=E5=A4=A9=E8=B5=8B=E6=A0=91:192-19?= =?UTF-8?q?9/=E9=94=BB=E9=80=A0=E5=B7=A5=E5=9D=8A:215-220/=E5=85=83?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6/=E5=AD=98=E6=A1=A3=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E5=8C=96:61-181/=E6=95=B0=E6=8D=AE=E9=85=8D=E7=BD=AE:199-204/?= =?UTF-8?q?=E5=9C=B0=E5=BD=A2=E5=8F=98=E5=BC=82:153/=E5=A5=87=E7=89=A9/?= =?UTF-8?q?=E5=85=B3=E5=8D=A1=E8=8A=82=E7=82=B9=E5=9B=BE=E7=94=9F=E6=88=90?= =?UTF-8?q?:127-132),=E6=83=AF=E4=BE=8B=E4=B8=8E=E5=B0=81=E8=A3=85?= =?UTF-8?q?=E5=A5=97=E4=BB=B6=E9=94=9Acode-conventions:40/41=E4=B8=8Earchi?= =?UTF-8?q?tecture:89/103/107/144;=20=E6=9C=AC=E6=AD=A5=E5=87=AD=E6=8D=AE:?= =?UTF-8?q?=2033=E5=A5=97=E4=BB=B6exit=3D0+run=5Ftime=5Ffatal=3D1(?= =?UTF-8?q?=E5=9C=A8=E5=86=8C=E8=B4=9F=E7=A0=81)=E5=85=A8=E9=87=8F?= =?UTF-8?q?=E7=9B=B4=E8=B7=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/tests/unit/core/adventure_feats_test.gd | 4 ++++ game/tests/unit/core/auto_player_deduce_test.gd | 1 + game/tests/unit/core/battle_driver_drive_test.gd | 4 ++++ game/tests/unit/core/board_gen_reward_test.gd | 5 +++++ game/tests/unit/core/board_generator_test.gd | 7 +++++++ game/tests/unit/core/breakpoint_resume_test.gd | 1 + .../unit/core/config_db_cross_validator_test.gd | 4 ++++ game/tests/unit/core/config_db_resolver_test.gd | 7 +++++++ game/tests/unit/core/curio_refresh_paid_test.gd | 1 + game/tests/unit/core/effect_words_t1_test.gd | 1 + game/tests/unit/core/encapsulation_p2_sweep_test.gd | 6 ++++++ game/tests/unit/core/encapsulation_sweep_test.gd | 10 ++++++++++ game/tests/unit/core/feat_vouchers_test.gd | 1 + game/tests/unit/core/hero_ledger_test.gd | 1 + game/tests/unit/core/level_map_type_vis_test.gd | 8 ++++++++ game/tests/unit/core/level_shop_economy_test.gd | 13 +++++++++++++ game/tests/unit/core/level_table_validate_test.gd | 4 ++++ game/tests/unit/core/meta_progression_forge_test.gd | 11 +++++++++++ game/tests/unit/core/minesweeper_rules_test.gd | 7 +++++++ game/tests/unit/core/node_map_generator_test.gd | 10 ++++++++++ game/tests/unit/core/node_map_growth_test.gd | 3 +++ game/tests/unit/core/playtest_logger_guard_test.gd | 1 + game/tests/unit/core/pool_case_d_test.gd | 5 +++++ game/tests/unit/core/run_time_fatal_test.gd | 1 + game/tests/unit/core/save_boot_no_activate_test.gd | 4 ++++ game/tests/unit/core/save_manager_domain_test.gd | 2 ++ game/tests/unit/core/save_slot_isolation_test.gd | 3 +++ game/tests/unit/core/save_slot_summary_test.gd | 3 +++ game/tests/unit/core/settle_segments_test.gd | 1 + game/tests/unit/core/treasure_effects_test.gd | 1 + game/tests/unit/core/treasure_items_test.gd | 1 + game/tests/unit/core/tree_requires_level_test.gd | 1 + game/tests/unit/core/tree_rules_v11_test.gd | 2 ++ 33 files changed, 134 insertions(+) diff --git a/game/tests/unit/core/adventure_feats_test.gd b/game/tests/unit/core/adventure_feats_test.gd index 8d78c4c6..623a42e7 100644 --- a/game/tests/unit/core/adventure_feats_test.gd +++ b/game/tests/unit/core/adventure_feats_test.gd @@ -17,6 +17,7 @@ var _db func _init() -> void: +# oracle: design/gdd/systems/冒险循环/冒险结构.md:281 冒险结构与专长宿主(装载组) _db = ConfigDBScript.new() # 表加载失败不中止(承 G2/G3/G4/G5 同款:表损坏的红落在具体断言上—— # 诊断在此展开,后续断言按坏表实况逐条验红;collect_only=true 下成员照常赋值可评) @@ -58,6 +59,7 @@ func _hits_kind(hits: Array, kind: String) -> Array: # ② 冒险结构 API 闸(状态机受理面——重复开始拒绝 / 入口停点 / 放弃两态) func _smoke_adventure_api() -> void: +# 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) # 首战速胜档(放弃的非战斗受理要走到选路态) @@ -120,6 +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(冒险生命周期组:推进/末关/倒下/重开/生命账) print("--- 冒险结构验收(三关序列 · 大奖励 · 摘要五件事 · 账本封闭)---") var autoplay = load("res://sim/level_autoplay.gd") # ① 表与覆盖义务(序列关数 = 行集关数;节点源 = 参数档在固定种子下的生成图, @@ -460,6 +463,7 @@ func _smoke_adventure() -> void: # ---- 专长冒烟(feats 四级 · 案D 池接线 · V3 订阅面逐件三列)---- func _smoke_feats() -> void: +# 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 380e7865..f9dfcb0b 100644 --- a/game/tests/unit/core/auto_player_deduce_test.gd +++ b/game/tests/unit/core/auto_player_deduce_test.gd @@ -16,6 +16,7 @@ func _init() -> void: func _smoke_zero_chain_rule() -> void: +# 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 43ba5e85..706aa28e 100644 --- a/game/tests/unit/core/battle_driver_drive_test.gd +++ b/game/tests/unit/core/battle_driver_drive_test.gd @@ -55,6 +55,7 @@ func _init() -> void: # ① 缺省两参(真编排器):同种子两跑整轮驱动逐位(确定性自证——动作序列快照经 cell_revealed 事件流) func _smoke_drive_round_contract() -> void: +# 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) @@ -80,6 +81,7 @@ func _smoke_drive_round_contract() -> void: # ② provider 形态:策略回调产出 dig/seal_place/refresh 各一——提交与日志回调四元组在案 func _provider_shapes() -> void: +# 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 = [] @@ -100,6 +102,7 @@ func _provider_shapes() -> void: # ③ max_rejects:策略恒返被拒动作——第 3 拒后停手出环(循环次数=3) func _max_rejects() -> void: +# oracle: design/engineering/architecture/architecture.md:144(拒绝通道组) var st := _StubSettlement.new() st.minesweeper.accept = false st.minesweeper.reject_cells = {Vector2i(9, 9): true} @@ -119,6 +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(合并步进组) 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 e7dd0c4f..3f465f05 100644 --- a/game/tests/unit/core/board_gen_reward_test.gd +++ b/game/tests/unit/core/board_gen_reward_test.gd @@ -18,6 +18,7 @@ var _rng func _init() -> void: +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:219 棋盘生成宿主(装载组) _db = ConfigDBScript.new() # 表加载失败不中止(承 G2 同款:表损坏的红落在具体断言上—— # 诊断在此展开,后续断言按坏表实况逐条验红;collect_only=true 下成员照常赋值可评) @@ -51,6 +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(出生区边长表单点——格边长公式组) print("--- 棋盘布局格边长公式(底部预留回归·四档板型)---") var board_generator = load("res://core/board_generator.gd").new() var board_view = load("res://presentation/views/board_view.gd").new() @@ -80,6 +82,7 @@ func _smoke_layout_cell_formula() -> void: # ---- 地图战斗资源·身份面单元冒烟(格面资源:roll 恰一次 / 雷安同池 / 幂等 / 清图批尾)---- func _smoke_reward_identity_unit() -> void: +# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:233(格面资源身份——三分出口与资源身份组) print("--- 地图战斗资源·格面资源身份面 ---") var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(20260911) @@ -141,6 +144,7 @@ class _BoardRowStub: func _smoke_board_generator() -> void: +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:221(确定性复现+布雷纪律组) print("--- 棋盘生成 ---") var board_generator = load("res://core/board_generator.gd").new() for L in [1, 2]: @@ -235,6 +239,7 @@ func _board_dump(b) -> String: # ---- 地图战斗资源·伤害量值区间冒烟(roll 域内 + 中点锚 + 变异实际流动 + 定值行不受扰)---- func _smoke_power_interval() -> void: +# 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 4acd338d..182794f0 100644 --- a/game/tests/unit/core/board_generator_test.gd +++ b/game/tests/unit/core/board_generator_test.gd @@ -13,6 +13,7 @@ var _db: ConfigDb func _init() -> void: +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:219 棋盘生成(装载组) _db = load("res://core/config_db.gd").new() as ConfigDb if not _db.load_tables("res://data/tables", false): Kit.check("数值表加载", false) @@ -39,6 +40,7 @@ func _generate(L: int, D: int, seed0: int) -> BoardData: func _test_generate_shape_and_mines() -> void: +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:224(布雷纪律组) var b := _generate(1, 0, 71000) if b == null: Kit.check("生成返回棋盘", false) @@ -59,6 +61,7 @@ func _test_generate_shape_and_mines() -> void: # 目标雷数公式单点(d14):同参同值对拍原式 + 真实产图指标读数同源 func _test_target_mine_count_single_source() -> void: +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:224(雷数单源组) var bad := 0 var checked := 0 for L in [1, 2, 3]: @@ -89,6 +92,7 @@ func _test_target_mine_count_single_source() -> void: func _test_digits_equal_neighbor_mine_count() -> void: +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:223(数字恒真组) var b := _generate(1, 1, 72000) if b == null: Kit.check("生成返回棋盘(数字段)", false) @@ -109,6 +113,7 @@ func _test_digits_equal_neighbor_mine_count() -> void: func _test_same_seed_bit_identical() -> void: +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:221(同种子逐位复现组) var a := _generate(2, 0, 73000) var b := _generate(2, 0, 73000) if a == null or b == null: @@ -119,6 +124,7 @@ func _test_same_seed_bit_identical() -> void: func _test_clearable_and_inferability_selfconsistent() -> void: +# oracle: design/gdd/systems/排雷循环/棋盘生成.md:226(可清图与及格线自洽组) var b := _generate(1, 0, 74000) if b == null: Kit.check("生成返回棋盘(可推理段)", false) @@ -134,6 +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(出生区边长读表组) # ① 纯函数对拍: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 9de8b519..c68200b9 100644 --- a/game/tests/unit/core/breakpoint_resume_test.gd +++ b/game/tests/unit/core/breakpoint_resume_test.gd @@ -15,6 +15,7 @@ var _bp_path := "user://test_breakpoint_resume.json" func _init() -> void: +# 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 8ad71acb..0b82f07d 100644 --- a/game/tests/unit/core/config_db_cross_validator_test.gd +++ b/game/tests/unit/core/config_db_cross_validator_test.gd @@ -13,6 +13,7 @@ const StatusTableScript := preload("res://data/schemas/status_effect_table.gd") func _init() -> void: +# oracle: design/gdd/systems/表现与支撑/数据配置.md:195(跨表校验宿主——装载组) _test_all_links_valid() _test_dangling_skill_id() _test_cast_side_mismatch() @@ -46,6 +47,7 @@ func _cats(errs: Array) -> Array[String]: # ---- 正向:技能池全对齿(普攻恰一行、buff 挂敌方侧)应零错,防校验误伤 ---- func _test_all_links_valid() -> void: +# oracle: design/gdd/systems/表现与支撑/数据配置.md:195(悬空引用类别:跨表链接全有效组) var skills := _skill([ {"skill_id": "attack", "type": "basic"}, {"skill_id": "raise_morale", "type": "buff", "buff_ref": "st_strong"}, @@ -61,6 +63,7 @@ func _test_all_links_valid() -> void: # ---- 负向:技能池引用表里不存在的 skill_id 必须报 ---- func _test_dangling_skill_id() -> void: +# 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": [ @@ -73,6 +76,7 @@ func _test_dangling_skill_id() -> void: # ---- 负向:buff 挂到主角侧状态(side 反向)必须报 ---- func _test_cast_side_mismatch() -> void: +# 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 a28f2472..40626662 100644 --- a/game/tests/unit/core/config_db_resolver_test.gd +++ b/game/tests/unit/core/config_db_resolver_test.gd @@ -12,6 +12,7 @@ var _resolver: ConfigDbResolver func _init() -> void: +# 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)]), @@ -54,6 +55,7 @@ func _difficulty_table(): func _test_band_hit() -> void: +# 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") @@ -63,6 +65,7 @@ func _test_band_hit() -> void: func _test_rowset_order_preserved() -> void: +# oracle: design/gdd/systems/表现与支撑/数据配置.md:202(行集寻址与行序保序组) var rows: Array = _resolver.resolve_enemy_rowset(1, 0, "battle") var ids: Array[String] = [] for r in rows: @@ -72,6 +75,7 @@ func _test_rowset_order_preserved() -> void: func _test_top_band_clamp() -> void: +# oracle: design/gdd/systems/表现与支撑/数据配置.md:202(超最大行走封顶取最大行组) _diags.clear() var rows: Array = _resolver.resolve_enemy_rowset(1, 99, "battle") Kit.check("越顶带 clamp 取顶带行集(battle 顶带 5)〔fv3〕", @@ -87,6 +91,7 @@ func _test_top_band_clamp() -> void: func _test_row_kind_routing() -> void: +# 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〕", @@ -95,6 +100,7 @@ func _test_row_kind_routing() -> void: func _test_request_oob() -> void: +# 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()) @@ -114,6 +120,7 @@ func _has_fatal_oob() -> bool: func _test_difficulty_clamp() -> void: +# 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 ca6fb88e..94e2a06f 100644 --- a/game/tests/unit/core/curio_refresh_paid_test.gd +++ b/game/tests/unit/core/curio_refresh_paid_test.gd @@ -8,6 +8,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: +# 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 0b1a196b..265ff860 100644 --- a/game/tests/unit/core/effect_words_t1_test.gd +++ b/game/tests/unit/core/effect_words_t1_test.gd @@ -11,6 +11,7 @@ const EffectEngineScript = preload("res://core/effect_engine.gd") func _init() -> void: +# 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 5bfa81e5..3e55fad3 100644 --- a/game/tests/unit/core/encapsulation_p2_sweep_test.gd +++ b/game/tests/unit/core/encapsulation_p2_sweep_test.gd @@ -11,29 +11,34 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: +# 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(源码采样组) 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(零命中扫描组) 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(正锚存在组) 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(生成器本地副本归零组) var src := _src("res://core/node_map_generator.gd") if src.length() == 0: return @@ -43,6 +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 唯一定点组) 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 56acd449..06af956c 100644 --- a/game/tests/unit/core/encapsulation_sweep_test.gd +++ b/game/tests/unit/core/encapsulation_sweep_test.gd @@ -14,6 +14,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: +# oracle: design/engineering/code-conventions.md:41(封装边界——五处结构性零命中扫描组) _sweep_settlement_segments() _sweep_orchestrator_methods() _sweep_breakpoint_pair() @@ -25,6 +26,7 @@ func _init() -> void: # 源文件读取+非空前置(返 "" 即已判红——调用侧跳过后续正则断言) func _src(path: String) -> String: +# oracle: design/engineering/code-conventions.md:41(源码采样组) var src := FileAccess.get_file_as_string(path) Kit.check("扫描面非空前置:%s" % path, src.length() > 0) return src @@ -32,18 +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(零命中扫描组) 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(正锚存在组) 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(结算段封装扫描组) var classes := { "res://core/settlement/grant_segment.gd": "GrantSegment", "res://core/settlement/combat_segment.gd": "CombatSegment", @@ -63,6 +68,7 @@ func _sweep_settlement_segments() -> void: # ② V3 编排器搬家五方法零残留 func _sweep_orchestrator_methods() -> void: +# oracle: design/engineering/code-conventions.md:41(编排器方法面扫描组) var src := _src("res://core/battle_orchestrator.gd") if src.length() == 0: return @@ -72,6 +78,7 @@ func _sweep_orchestrator_methods() -> void: # ③ V4 断点域(adventure_runner → BreakpointStore 公开面) func _sweep_breakpoint_pair() -> void: +# oracle: design/engineering/code-conventions.md:41(断点对封装扫描组) var src := _src("res://core/adventure_runner.gd") if src.length() == 0: return @@ -81,6 +88,7 @@ func _sweep_breakpoint_pair() -> void: # ④ V5 存档双向公开面(save_manager↔slot_store) func _sweep_save_pair() -> void: +# 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") @@ -94,6 +102,7 @@ func _sweep_save_pair() -> void: # ⑤ V6 效果宿主累积面(grant → BattleFxHost 公开累积方法) func _sweep_fx_host_accumulators() -> void: +# oracle: design/engineering/code-conventions.md:41(特效宿主累积面扫描组) var src := _src("res://core/settlement/grant_segment.gd") if src.length() == 0: return @@ -103,6 +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(配置挂载面扫描组) 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 4e4cc4ac..cda7db0d 100644 --- a/game/tests/unit/core/feat_vouchers_test.gd +++ b/game/tests/unit/core/feat_vouchers_test.gd @@ -16,6 +16,7 @@ func EffectEngineKindProbe(_db) -> bool: func _init() -> void: +# 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 4102292b..e8e30b4c 100644 --- a/game/tests/unit/core/hero_ledger_test.gd +++ b/game/tests/unit/core/hero_ledger_test.gd @@ -14,6 +14,7 @@ const LevelRunnerScript := preload("res://core/level_runner.gd") func _init() -> void: +# 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 d1bade78..f97fdd19 100644 --- a/game/tests/unit/core/level_map_type_vis_test.gd +++ b/game/tests/unit/core/level_map_type_vis_test.gd @@ -10,6 +10,7 @@ const LevelTableScript := preload("res://data/schemas/level_table.gd") func _init() -> void: +# 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, "可见性用例:数值表加载成功") @@ -102,6 +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(迷雾参数读表——字段在表组) 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() @@ -125,6 +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 可见性组) var nodes := _graph_nodes() var r = _runner(db, nodes, 1, [nodes[2]]) # 锚 = 节点 1(层 1),候选 = 节点 2 var vis: Array = r.type_visible_ids() @@ -136,6 +139,7 @@ func _test_layer_distance(db) -> void: # ---- ② 下一跳恒可见(跨层跳边候选)〔fv4〕---- func _test_candidate_exempt(db) -> void: +# 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() @@ -146,6 +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 豁免组) var nodes := _graph_nodes() var r = _runner(db, nodes, -1, [nodes[0]]) # 入口停点(无当前节点,锚层 0) var vis: Array = r.type_visible_ids() @@ -158,6 +163,7 @@ func _test_boss_exempt(db) -> void: # ---- ④ 单圈回雾(visited 不豁免)〔fv7〕---- func _test_single_circle(db) -> void: +# 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]]) @@ -170,6 +176,7 @@ func _test_single_circle(db) -> void: # ---- ⑤ 单链退化形态(出度 ≤1 图,编号 = id 句柄)〔fv1〕---- func _test_single_chain_entry(db) -> void: +# 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() @@ -182,6 +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 读表组) var nodes := _graph_nodes() var r = _runner(db, nodes, 1, [nodes[2]]) # 锚层 1 db.run.level.info_visible_layers = 1 diff --git a/game/tests/unit/core/level_shop_economy_test.gd b/game/tests/unit/core/level_shop_economy_test.gd index 5ddd10a9..7fafb4c9 100644 --- a/game/tests/unit/core/level_shop_economy_test.gd +++ b/game/tests/unit/core/level_shop_economy_test.gd @@ -261,6 +261,7 @@ func _init() -> void: # ---- 数值入表等价证明(d11/d16a——原字面量迁移:表值 == 迁移前字面量,消费端读表)---- func _smoke_table_migration() -> void: +# 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 == "探险者") @@ -275,6 +276,7 @@ func _smoke_table_migration() -> void: # 敌侧/板侧解析一律走 ConfigDB 真实消费链,禁直读行集自算)---- func _smoke_generated_coverage() -> void: +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:184(每终点前恰一店——生成覆盖扫描组) var enemy_ok := true var board_ok := true var boss_band_ok := true @@ -325,6 +327,7 @@ func _smoke_generated_coverage() -> void: # ---- 关卡节点图·生成图推进冒烟(图 = 该关参数档 × 种子)---- func _smoke_level() -> void: +# 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)} # 配置基线快照——⑤ 回基线对比用(改表自动跟随,不再硬编码) @@ -438,6 +441,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(图结构与行进纪律组) print("--- 关卡节点图·分支节点图(L2 幽暗地域·生成图)---") var autoplay = load("res://sim/level_autoplay.gd") # ① 关卡表行级校验零错误(关卡表只承载序号/显示名/恢复比例——图合法性由 validate_graph 在起关时承担) @@ -795,6 +799,7 @@ func _fresh_rng(seed_val: int): # ---- ① GP 冒险钱包·到账 ---- func _smoke_gp_wallet() -> void: +# 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 与钱包事件 @@ -860,6 +865,7 @@ func _escrow_sum_of(rows: Array) -> int: # ---- ② escrow 隔离(GP安全格兑付 / 破财直验 / 钱包 clamp)---- func _smoke_gp_escrow() -> void: +# oracle: design/gdd/systems/战斗循环/地图战斗资源.md:233(GP escrow 组) print("--- GP escrow 隔离(GP安全格兑付入缓冲 · 破财不透支)---") # ① 种子扫描:找GP 袋(gp 型安全格)可挖掘局——挖开兑付 +3 入 escrow,战斗末随 gp_dropped 一次上抛 var scan := {} @@ -973,6 +979,7 @@ func _find_gp_dig(minesweeper, settlement) -> Dictionary: # ---- ③ 商店房三收口 ---- func _smoke_shop_room() -> void: +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:184(商店房呈现组) print("--- 商店房三收口(现价/加算区/余额不足拒/离开回选路/收束清零)---") var autoplay = load("res://sim/level_autoplay.gd") # 行进到商店房(按图型别定位商店节点——候选取最小句柄行进,到达即停): @@ -1106,6 +1113,7 @@ func _shop_products_by_id(prods: Array) -> Dictionary: # ---- ④ 商店编排性质(生成图扫描面——三条性质 + 终点跨表解析)---- func _smoke_shop_graph() -> void: +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:184(必经恰一店图纪律组) print("--- 商店编排性质(每终点前一位恰一店 · 店数=终点数 · 全路径恰穿一店)---") var pred_bad := 0 var term_total := 0 @@ -1176,6 +1184,7 @@ func _smoke_shop_graph() -> void: # ---- ⑥ 大岔口分区域兑付(V3——多终点图走哪条路决定打谁,任一 Boss 胜即收束恰一次)---- func _smoke_multi_terminal_settlement() -> void: +# 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", []) @@ -1243,6 +1252,7 @@ func _paths_all_one_shop(nodes: Array) -> bool: # ---- ⑤ 商店共享池(三选一同构/乘法价/跨渠道共账/切边/断点扩键)---- func _smoke_shop_pool() -> void: +# oracle: design/engineering/architecture/architecture.md:107(商店共享池组) print("--- 商店共享池(抽3买1全重抽 · 乘法定价 ceil · 池空硬闸 · 切边零入店)---") var autoplay = load("res://sim/level_autoplay.gd") var shelf_kinds: Array = [] @@ -1405,6 +1415,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(行进至此打开商店覆盖层——载荷组) print("--- 商店房 node_entered 载荷(pool 含 shelf:true+gp 现值/legacy 无 shelf 键)---") var autoplay = load("res://sim/level_autoplay.gd") # pool 态:载荷字典经信号闭包当场取样(字典为引用累积器——lambda 按值捕获标量的绕行惯例) @@ -1563,6 +1574,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(货架位数读表组) var autoplay = load("res://sim/level_autoplay.gd") var st = _db.run.shop var saved: int = int(st.shelf_size) @@ -1584,6 +1596,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 与刷新折扣组) # 字段真删: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 437cdfee..b845d220 100644 --- a/game/tests/unit/core/level_table_validate_test.gd +++ b/game/tests/unit/core/level_table_validate_test.gd @@ -11,6 +11,7 @@ const LevelTableScript := preload("res://data/schemas/level_table.gd") func _init() -> void: +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178(关卡表消费侧校验宿主) _test_positive() _test_negative() _test_scope_not_extended() @@ -37,6 +38,7 @@ func _has(errs: Array, cat: String, needle: String = "") -> bool: # ---- 正例(四检全过)---- func _test_positive() -> void: +# oracle: design/gdd/systems/冒险循环/关卡节点地图.md:178(良构基底正向组) # 多入口多终点:两入口共汇入一岔口,两终点各在互异深度 var multi := [ _n(0, "battle", 0, [2]), _n(1, "battle", 0, [2]), @@ -59,6 +61,7 @@ func _test_positive() -> void: # ---- 负例九类(各报对应类别与判据消息)---- func _test_negative() -> void: +# 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")) @@ -92,6 +95,7 @@ func _test_negative() -> void: # ---- 「勿扩勿缩」反证:本检不含商店位与个数对参数档的核对 ---- func _test_scope_not_extended() -> void: +# 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 84bdd583..1e4af588 100644 --- a/game/tests/unit/core/meta_progression_forge_test.gd +++ b/game/tests/unit/core/meta_progression_forge_test.gd @@ -21,6 +21,7 @@ var _db func _init() -> void: +# oracle: design/gdd/systems/跨局循环/元进度.md:148 元进度与锻造宿主(装载组) _db = ConfigDBScript.new() # 表加载失败不中止(承 G2/G3/G4/G5 同款:表损坏的红落在具体断言上—— # 诊断在此展开,后续断言按坏表实况逐条验红;collect_only=true 下成员照常赋值可评) @@ -132,6 +133,7 @@ func _auto_play_round(settlement, out: Dictionary) -> void: # ---- 元进度 ②树购买面(购买受理/持久/余额不足拒绝/未知节点拒绝; # 行价=表值 flat 单价)---- func _meta_pricing_and_buy() -> void: +# oracle: design/gdd/systems/跨局循环/天赋树.md:198(单币可判:购买只扣钥石、余额不足拒绝零变化组) print("--- 元进度·树购买面(隔离档 smoke_meta_buy/dry)---") _meta_smoke_cleanup() var sv = _meta_new_save(_META_SMOKE_PATHS[0]) @@ -158,6 +160,7 @@ func _meta_pricing_and_buy() -> void: # ---- 元进度 ⑥Boss 两档 ⑦钥石不丢 ⑧工坊解锁 ⑩摘要副本与 cap(合成摘要驱动——settle 纯账面零跑局)---- func _meta_settle_and_workshop() -> void: +# 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) @@ -350,6 +353,7 @@ func _meta_settle_and_workshop() -> void: # ---- 元进度 ④注入可见 + 白板成立(验收 4/2/3——程序面;MC 逐位回归归 T7 全量验证)---- func _meta_injection() -> void: +# 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) @@ -393,6 +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(锻造两轴单选注入与树零攻防组) print("--- 锻造工坊·类型轴所有权移交(T2)---") # V5:hero.tres 静态表两轴已删(全表加载零违例——config_db_test 同款闸;此处钉字段不在位) Kit.check("hero.tres 无 attack_type/armor_type 字段(契约 2——静态表两轴删除)〔锻造工坊批 V5〕", @@ -555,6 +560,7 @@ func _smoke_forge_axes() -> void: # ---- 天赋树冒烟(v0.8 12 节点:schema/购买面/Fork 一节点双态/彩蛋特化)---- func _smoke_tree() -> void: +# 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〕", @@ -637,6 +643,7 @@ func _smoke_tree() -> void: # ---- 天赋树六键行为冒烟(V10:开局姿态窗/危险直觉限次/财富之道聚散/守侧失误补偿; # 引擎直构 + 编排授予段直注(_grant_seg._judge_seal=结算授予段封印判定单口))---- func _smoke_tree_rules() -> void: +# oracle: design/gdd/systems/跨局循环/天赋树.md:194(规则键参数读表组) print("--- 天赋树六键行为(V10:窗/限次/聚散/守侧)---") # 开局姿态组:每关首轮窗(battle_index 事实——引擎直构 + 自建 ctx) var fx = load("res://core/effect_engine.gd").new(null) @@ -777,6 +784,7 @@ func _smoke_tree_rules() -> void: # ---- 锻造契约补齐(断言补齐批——⑥锻造工坊):拒购零副作用/祝福件零泄漏/默认值解耦/甲型双轴 ---- func _test_forge_buy_reject() -> void: +# 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——余额不足面 @@ -791,6 +799,7 @@ func _test_forge_buy_reject() -> void: func _test_blessing_no_forge_leak() -> void: +# 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) @@ -809,6 +818,7 @@ func _test_blessing_no_forge_leak() -> void: func _test_default_axes_pre_key() -> void: +# 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() @@ -817,6 +827,7 @@ func _test_default_axes_pre_key() -> void: func _test_armor_switch_dual_axes() -> void: +# 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 5f4bdcc0..cb3b50ba 100644 --- a/game/tests/unit/core/minesweeper_rules_test.gd +++ b/game/tests/unit/core/minesweeper_rules_test.gd @@ -17,6 +17,7 @@ var _ae: ActionEconomy func _init() -> void: +# 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) @@ -45,6 +46,7 @@ func _init() -> void: func _test_install_invariants() -> void: +# 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() @@ -68,6 +70,7 @@ func _unrevealed_safe() -> Vector2i: func _test_dig_face_rules() -> void: +# 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 {} @@ -82,6 +85,7 @@ func _test_dig_face_rules() -> void: func _test_reveal_advances() -> void: +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:230(揭示推进与连锁组) var c := _unrevealed_safe() if c == Vector2i(-1, -1): Kit.check("存在未揭示安全格(揭示推进前置)", false) @@ -95,6 +99,7 @@ func _test_reveal_advances() -> void: func _test_seal_place() -> void: +# oracle: design/gdd/systems/排雷循环/排雷玩法.md:231(重复封印拒绝组) var c := _unrevealed_safe() if c == Vector2i(-1, -1): Kit.check("存在未揭示安全格(封印前置)", false) @@ -107,6 +112,7 @@ func _test_seal_place() -> void: func _test_reject_out_of_catalog() -> void: +# 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), @@ -116,6 +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 只读预览口——零写入零事件组) 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 1c1e8acb..c57b11a9 100644 --- a/game/tests/unit/core/node_map_generator_test.gd +++ b/game/tests/unit/core/node_map_generator_test.gd @@ -77,6 +77,7 @@ func _max_depth(g: Dictionary) -> int: # ---- V1 产出合格:三档×种子扫描,自证零错误 ---- func _test_output_ok() -> void: +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:129(产出约束六条+结构铁律组) var all_ok := true var entry_exit_ok := true for L in [1, 2, 3]: @@ -94,6 +95,7 @@ func _test_output_ok() -> void: # ---- V3 可复现:纯函数+counter 无关 ---- func _test_reproducible() -> void: +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:134(同种子同参数同图组) var same := true for L in [1, 2, 3]: if _sig(_graph(L, 42)) != _sig(_graph(L, 42)): @@ -124,6 +126,7 @@ func _test_reproducible() -> void: # ---- V5 岔路取舍两条 ---- func _test_fork_rules() -> void: +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:88(岔路取舍组) var next_hop_ok := true var comp_ok := true for L in [1, 2, 3]: @@ -199,6 +202,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(必经恰一店与归属锁定组) var paths_ok := true var lock_ok := true var depth_ok := true @@ -251,6 +255,7 @@ func _all_paths(g: Dictionary) -> Array: # ---- V7 战斗保底 ---- func _test_battle_floor() -> void: +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:129(战斗保底组) var ok := true for L in [1, 2, 3]: for s in range(42, 52): @@ -262,6 +267,7 @@ func _test_battle_floor() -> void: # ---- V9 含岔口与出口结构 ---- func _test_exit_structure() -> void: +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:48(出口结构与分支互斥组) var fork_all := true var l1_single := true var big_fork_ok := true @@ -308,6 +314,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 出口组) # 真实生成多区域图:全部终点 type=="boss"、boss 终点数==exit_count、深度=L−r(r∈[0,exit_count) # ——每区域恰一 boss、深度互异即分属不同区域) # 节点 depth 字段=入口起最长路径深(生成器校验轴);区域序号 r 的可观测形态=最深 boss(r=0) @@ -343,6 +350,7 @@ func _test_boss_exit_per_region() -> void: # ---- V10 RNG 单点(纯流面 counter 不变)---- func _test_rng_single_point() -> void: +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:134(RNG 单点流组) var svc = RngScript.new() svc.new_adventure(4242) var before: int = svc.counter() @@ -357,6 +365,7 @@ func _test_rng_single_point() -> void: # ---- V1 违规夹具:各报对应错误类别 ---- func _test_negative_fixtures() -> void: +# oracle: design/gdd/systems/表现与支撑/数据配置.md:198(无解 fail-fast 夹具组) # 夹具构造器:手写 nodes/entries/terminals var dup := _fx([ {"id": 0, "type": "battle", "depth": 0, "next": [1]}, @@ -483,6 +492,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(参数档读表驱动组) # ① 同种子真实表行产图逐位(表值驱动回归锚) 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 3ab25ad9..864b8674 100644 --- a/game/tests/unit/core/node_map_growth_test.gd +++ b/game/tests/unit/core/node_map_growth_test.gd @@ -38,6 +38,7 @@ func _reading(gen, db, L: int) -> Dictionary: # ---- V8 生长递增(三档×多种子逐档读数)---- func _test_growth(gen, db) -> void: +# oracle: design/gdd/systems/冒险循环/关卡节点图生成.md:130(生长递增组) var steps_ok := true var count_ok := true for s in [42, 43, 44, 45, 46]: @@ -61,6 +62,7 @@ func _test_growth(gen, db) -> void: # ---- V4 参数无解判定(静态面:域/预算无解夹具必须被 check_params 拦下)---- func _test_fail_fast_static(gen, db) -> void: +# 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()) @@ -79,6 +81,7 @@ func _test_fail_fast_static(gen, db) -> void: # ---- V4 致命中止真实通道(子进程退出码非零;零回退分支=件核)---- func _test_fatal_subprocess() -> void: +# oracle: design/gdd/systems/表现与支撑/数据配置.md:199(无解致命子进程组) var bin := _engine_bin() if bin == "": Kit.check("未找到引擎二进制,致命子进程通道未跑(如实标注)〔fv4〕", false) diff --git a/game/tests/unit/core/playtest_logger_guard_test.gd b/game/tests/unit/core/playtest_logger_guard_test.gd index 1f1ec9eb..670be3ab 100644 --- a/game/tests/unit/core/playtest_logger_guard_test.gd +++ b/game/tests/unit/core/playtest_logger_guard_test.gd @@ -13,6 +13,7 @@ func _init() -> void: func _smoke_required_injection() -> void: +# 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 86aabf8d..814af348 100644 --- a/game/tests/unit/core/pool_case_d_test.gd +++ b/game/tests/unit/core/pool_case_d_test.gd @@ -9,6 +9,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: +# 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 — 数值表加载失败") @@ -65,6 +66,7 @@ func _tiers_of(cands: Array) -> Array: func check_v7(a, db) -> void: +# oracle: design/engineering/architecture/architecture.md:107(池案 D V7 组) if not a.start_adventure(201): Kit.check_quiet(false, "V7 前置:冒险启动") return @@ -110,6 +112,7 @@ func check_v7(a, db) -> void: func check_v6(b, db) -> void: +# oracle: design/engineering/architecture/architecture.md:107(池案 D V6 组) if not b.start_adventure(202): Kit.check_quiet(false, "V6 前置:冒险启动") return @@ -139,6 +142,7 @@ func check_v6(b, db) -> void: func check_v12(m, db) -> void: +# oracle: design/engineering/architecture/architecture.md:107(池案 D V12 组) if not m.start_adventure(401): Kit.check_quiet(false, "V12 前置:冒险启动") return @@ -157,6 +161,7 @@ func check_v12(m, db) -> void: func check_v8(c, db) -> void: +# 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 cd80a919..0178c303 100644 --- a/game/tests/unit/core/run_time_fatal_test.gd +++ b/game/tests/unit/core/run_time_fatal_test.gd @@ -20,6 +20,7 @@ const TAG_OK := "board_gen" # 在册合法标签(PURPOSE_TAGS 含;wr7 必 func _init() -> void: +# 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] 表加载失败——夹具不可用(回归)") 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 7345c8e5..262b88b7 100644 --- a/game/tests/unit/core/save_boot_no_activate_test.gd +++ b/game/tests/unit/core/save_boot_no_activate_test.gd @@ -22,6 +22,7 @@ func _init() -> void: # ① 无参实例(autoload 实例化形态)=无激活态+默认合法空态(sv2 类级) func _test_no_arg_instance_has_no_activation() -> void: +# 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〕") @@ -40,6 +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(无激活态写盘拒绝组) var sm := SaveManagerScript.new() var before := {} for i in range(1, 4): @@ -79,6 +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(结算链写盘拒绝组) var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): Kit.check_quiet(false, "sv3 链测试前置:数值表加载失败〔卡① sv3〕") @@ -101,6 +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(三存档位域界——越域槽拒绝组) 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 4574f1c9..bb47f190 100644 --- a/game/tests/unit/core/save_manager_domain_test.gd +++ b/game/tests/unit/core/save_manager_domain_test.gd @@ -46,6 +46,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(存档域读写往返/迁移链/损坏兜底/域界组) print("--- SaveManager 存档读写/迁移/兜底 ---") var sm_script = load("res://core/save_manager.gd") var paths := ["user://smoke_save_roundtrip.json", "user://smoke_save_fresh.json", @@ -338,6 +339,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——槽位域组) 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 9d7070c8..6afdd4fe 100644 --- a/game/tests/unit/core/save_slot_isolation_test.gd +++ b/game/tests/unit/core/save_slot_isolation_test.gd @@ -38,6 +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(三槽位独立文件隔离组) var t := SaveManagerScript.new() t.slots.attach_slot_template(TPL) for i in range(1, 4): @@ -65,6 +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(激活失败回滚组) var t := SaveManagerScript.new() t.slots.attach_slot_template(TPL) _write_v7_keystone(TPL % 1, 311) @@ -86,6 +88,7 @@ func _test_activate_failure_restores_previous_slot() -> void: # ③ MetaProgression 宿主链切槽:引用同一性保持+写盘落当前槽(sv10——禁换实例先例) func _test_metaprogression_reference_identity() -> void: +# 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 468045c9..b4354562 100644 --- a/game/tests/unit/core/save_slot_summary_test.gd +++ b/game/tests/unit/core/save_slot_summary_test.gd @@ -36,6 +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(槽位摘要按槽窥视组) var t := SaveManagerScript.new() t.slots.attach_slot_template(TPL) for i in range(1, 4): @@ -57,6 +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(坏槽三态组) var t := SaveManagerScript.new() t.slots.attach_slot_template(TPL) DirAccess.remove_absolute(TPL % 3) # 清①段残留——空槽夹具 @@ -77,6 +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(窥视零副作用组) 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 4002bdd8..edebe932 100644 --- a/game/tests/unit/core/settle_segments_test.gd +++ b/game/tests/unit/core/settle_segments_test.gd @@ -9,6 +9,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: +# 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 75d66779..16e184c7 100644 --- a/game/tests/unit/core/treasure_effects_test.gd +++ b/game/tests/unit/core/treasure_effects_test.gd @@ -10,6 +10,7 @@ const Kit := preload("res://tests/unit/test_kit.gd") func _init() -> void: +# 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 1560646d..c46ee17f 100644 --- a/game/tests/unit/core/treasure_items_test.gd +++ b/game/tests/unit/core/treasure_items_test.gd @@ -53,6 +53,7 @@ func _all_revealed(_c: Vector2i) -> bool: func _init() -> void: +# 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 8b189ab7..1434ce5a 100644 --- a/game/tests/unit/core/tree_requires_level_test.gd +++ b/game/tests/unit/core/tree_requires_level_test.gd @@ -7,6 +7,7 @@ extends SceneTree func _init() -> void: +# 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 8c791eb7..834881ef 100644 --- a/game/tests/unit/core/tree_rules_v11_test.gd +++ b/game/tests/unit/core/tree_rules_v11_test.gd @@ -12,6 +12,7 @@ extends SceneTree func _init() -> void: +# 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() @@ -88,6 +89,7 @@ func _init() -> void: # ---- 规则键参数域校验(架构整改批 R1——六键参数字典):正例全过/缺参数拒/多参数拒/越域拒/非字典拒 ---- func _test_rule_key_params(eng, tree_tbl, db) -> Array: +# oracle: design/gdd/systems/跨局循环/天赋树.md:194(规则键参数字典——参数名/取值域合规组) var errs: Array = [] var params_tbl: Dictionary = tree_tbl.RULE_KEY_PARAMS # 正例:meta_tree.tres 现行 Fork 行逐键过 validate(加载期已验——此处显式复核)