49 KiB
Dungeon Sweeper — 总体架构文档
文档状态
- 版本:1.12
- 最近更新:2026-10-25(S6/S7/S8 三闸落地批收口——静态扫描承接清单三行改在位;2026-10-25 用户发令三闸落地)
- 引擎:Godot 4.7.2-stable(GDScript 单语言;2026-09-07 锁定)
- 评审模式:solo(
review-mode.txt,2026-09-12 用户拍板——TD/LP 门禁按 solo 跳过,用户授权架构产出自主推进、迭代期回调) - 覆盖 GDD:现行全集——
design/gdd/顶层 00–08 共 9 件 +systems/五域 25 件(排雷循环 4 / 战斗循环 5 / 冒险循环 5 / 跨局循环 5 / 表现与支撑 6)+ux/8 件;原英文命名 12 份系统 GDD 已全部迁入中文域目录,原「未设计」预留(A5 扫雷秘宝 / C1–C4 / B5 / D3–D6)均已立项成文 - 事实源地位:本文是架构事实的唯一来源——分层/所有权/数据流/API 边界/测试与质量域均以本文为准;历史决策沿革查 git commit log,不另设决策文档体系
- 实现实证:
game/(2026-09-10 起开发,现为完整游戏开发版本,已非垂直切片;测试层级=冒烟/单元/集成/系统四级+UI 探针与渲染 golden(2026-10-22 用户裁,测试术语与层级重构批),闸机按改动域分跑在役)——本文档的分层/所有权/数据流均经实现验证,非纯纸面设计 - 技术总监签核:2026-09-12 — 有条件通过(原条件「决策记录须于正式工程骨架前定稿」已满足:骨架已成、沿革在 git 历史可查;
.claude/docs/director-gates.md缺失已登记技术债) - 主程序可行性:跳过 — solo 模式
引擎知识缺口摘要
- 风险等级:MEDIUM(2026-09-12
/setup-engine refresh后由 HIGH 降级)。4.5→4.7 官方迁移指南已逐条核实并入design/engineering/engine-reference/godot/breaking-changes.md与deprecated-apis.md;结论:无一条破坏 GDD 已锁架构契约(autoload 体系 / .tres 单一事实源 / Callable 信号 / int64 二补数 / headless SceneTree 协议均不受影响)。 - 写码纪律不变:不确定的 API 一律查
docs.godotengine.org/en/4.7/核实后再用;4.8(dev 阶段)稳定版发布后跑/setup-engine refresh。 - 三类必须入编码纪律的引擎事实(详见
design/engineering/engine-reference/godot/current-best-practices.md):- GDScript 4.7 两条语义变化:打包数组元素赋值不再触发属性 setter;类型化返回的方法覆盖必须显式
return。 - 新项目默认值已变:stretch mode
canvas_items/ aspectexpand(4.7);Windows 渲染驱动 D3D12(4.6,仅 Forward+ 线)——创建 project.godot 后逐项核对。 Resource.duplicate(true)深复制不再覆盖外部子资源——D2 表资源复制语义注意。
- GDScript 4.7 两条语义变化:打包数组元素赋值不再触发属性 setter;类型化返回的方法覆盖必须显式
- 残余风险敞口:modules/ 分域参考未建(按实现期需要建,非阻塞);UI/渲染域(D1/B5)为 MEDIUM 风险集中地——渲染器与窗口基座已定(gl_compatibility + 1280×800,2026-09-12),采纳引擎增量前对照文档核实。
系统分层图
20 系统按 design/gdd/02-系统清单.md 依赖分层表映射到标准五层。实现已验证该分层(core/ 纯逻辑零 UI 依赖 headless 可跑、presentation/ 组合根模式)。
┌────────────────────────────────────────────────────────────┐
│ 呈现层 │
│ D1 HUD 与界面框架 (MVP) · B5 战斗表现 │
│ D4 音频 (Beta) · D5 教学引导 (Beta) │
├────────────────────────────────────────────────────────────┤
│ 功能层 │
│ B1 战斗结算编排 (MVP) · C1 关卡节点地图 (lite 已实装) │
│ C2 冒险结构 · C3 难度曲线 · C4 元进度 (Alpha) │
├────────────────────────────────────────────────────────────┤
│ 核心层 │
│ A1 扫雷棋盘生成 · A2 排雷玩法规则 · B2 敌人系统 │
│ B4 地图战斗资源 · A5 扫雷秘宝 │
├────────────────────────────────────────────────────────────┤
│ 基础层 │
│ D2 数据配置与数值表 · A3 行动经济 · A4 地形变异 │
│ B3 增益/状态系统 · D3 存档序列化 (Alpha) · D6 设置/本地化│
├────────────────────────────────────────────────────────────┤
│ 平台层 │
│ Godot 4.7.2 引擎 API 面(GDScript / Resource / │
│ SceneTree / Control / InputEvent)——无游戏系统 │
└────────────────────────────────────────────────────────────┘
层名对照:基础层=Foundation、核心层=Core、功能层=Feature、呈现层=Presentation、平台层=Platform——本文一律用中文名;跨文档与代码目录仍见英文名(
game/core/、game/presentation/等目录名不改)。
| 系统 | 层 | 里程碑 | headless 约束 | 引擎风险域 |
|---|---|---|---|---|
| D2 数据配置 | 基础层 | MVP | ✅ 完整可跑 | LOW(Resource/.tres 基线稳定) |
| A3 行动经济 | 基础层 | MVP | ✅ 完整可跑 | LOW(纯逻辑) |
| A4 地形变异 | 基础层 | MVP | ✅ 完整可跑 | LOW(纯逻辑) |
| B3 状态系统 | 基础层 | MVP | ✅ 完整可跑 | LOW(RefCounted 纯逻辑) |
| A1 棋盘生成 | 核心层 | MVP | ✅ 完整可跑 | LOW(纯逻辑) |
| A2 排雷规则 | 核心层 | MVP | ✅ 完整可跑 | LOW(零表读取零 UI) |
| B2 敌人系统 | 核心层 | MVP | ✅ 完整可跑 | LOW(纯逻辑) |
| B4 地图战斗资源 | 核心层 | MVP | ✅ 完整可跑 | LOW(纯逻辑) |
| B1 战斗结算编排 | 功能层 | MVP | ✅ 完整可跑(禁 await) | LOW(纯逻辑) |
| C1 关卡节点地图 | 功能层 | MVP(切片期实装) | ✅(切片 level_runner 先例) | LOW |
| C2 冒险结构 | 功能层 | MVP(切片期实装) | ✅ | LOW |
| C3 难度曲线 | 功能层 | MVP(切片期实装) | ✅ | LOW |
| C4 元进度 | 功能层 | Alpha | ✅ | LOW |
| D1 HUD | 呈现层 | MVP | ❌(UI 层——场景级探针测试承载) | MEDIUM(Control/Input/文本域) |
| B5 战斗表现 | 呈现层 | 切片后立项(未实装,前置战斗表现美术测试) | ❌ | MEDIUM(Animation/Tween/渲染) |
| D4 音频 / D5 教学 | 呈现层 | Beta(2026-10-13 Alpha 版本标准裁:与游戏内容无关者一律排 Beta) | 部分 | LOW-MEDIUM |
| D3 存档序列化 | 基础层 | Alpha | ✅ | LOW |
| D6 设置/本地化 | 基础层 | 完整愿景 | ✅ | LOW |
MVP 关键路径(实现已验证):D2 → A3/A4/B3 → A1 → A2 → B2/B4 → B1 → D1-lite。 依赖分层与唯一回边:A2 只外发三事件(cell_revealed / flag_judged / round_end),B4/B1 订阅后回调——A2 不依赖任何下游(TD-SYSTEM-BOUNDARY 裁决,全项目唯一允许回边)。
模块归属
命名遵循
design/engineering/code-conventions.md:领域命名、禁 ID 前缀(文件头注不写文档链接——「实现 GDD:xxx」一类已废止,代码↔设计追溯由 GDD 文档承担)。切片已按此规范完成领域命名批。
基础层
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|---|---|---|---|---|
| ConfigDB(autoload,D2) | 全部玩法数值表(data/tables/*.tres + data/schemas/*.gd);SCHEMA_VERSION;加载/校验/override/诊断状态机 |
类型化属性读取;load_tables(root, collect_only);resolve()(R1 floor);debug override;set_reload_gate();诊断收集器 |
无(基础层顶点) | Resource/.tres 加载、autoload 生命周期——LOW |
| RngService(autoload,D2) | master_seed、各流 scope 计数器(封闭流:board_gen / reward_roll;增流走 P1 评审) | set_master_seed()(唯一调用方 C2);open_stream(stream) 有状态门面;derive_at(stream, scope) 纯函数;只读计数器 |
ConfigDB(无) | 无——纯逻辑 |
| action_economy(A3) | AP/RAP 账本、last_round_end、轮次相位机 {Idle, Active, Waiting}、结束仲裁 | 意图与通知布尔面:notify_round_start / request_dig / request_stop / request_refresh / notify_settlement_done / notify_combat_end;预授权通道:grant_reserve_ap / finish_round_stop;ap/rap/phase 只读 | ConfigDB(ActionEconomyTable);effect_engine(事件发射 dispatch——基础层内同层引用);B1 回发 next_round_mode/battle_over | 无 |
| variation 定义(A4) | VariationTable schema(现行 6 行:六 region——贫矿脉 global 行 2026-10-16 用户令屏蔽删行,global 型机制代码保留)与 F1 候选池门控谓词 | variant_pool(level_index, board_type, node_type="")(门控三维:unlock+board_types+节点身份——global 行仅 boss/elite 入池,缺省跳过零扰动);global_variant_row(level_index, board_type, node_type)(全局型单行决议访问器) |
ConfigDB(VariationTable) | 无 |
| status_container(B3) | 状态实例容器(战斗域生命周期、跨轮跨图延续) | 5 API:notify_battle_start / apply_effect / query_active / decay_round / notify_battle_end | ConfigDB(StatusEffectTable) | 无(RefCounted) |
| effect_engine(内容数据驱动扩展批 iter17 建域) | 零运行时可变状态的系统(见「架构原则」条 8):事件/事实/效果类型/算子四词表封闭(迭代 21 T3 扩签:EVENTS 18→19 +seal_missed 标错判定、FACTS +battle_index 关卡域战斗序)+ 树规则合成订阅六键(posture 每关首轮窗/sense 两组限次 counter 闸·adv_ 前缀走冒险桶跨战斗持久) | rebuild(每战重建订阅表)/dispatch(ctx, event, payload, facts)/validate_trigger_row + 静态计数口 counter·counter_add·counter_spend·bucket_of·counter_id_legal(计数器读写只经 EffectContext 引用束,无导出/灌入接口) |
ConfigDB(feats/treasure 行集)、EffectContext(四桶引用由宿主持有:round/battle 桶归编排器、level 桶归关卡域、adventure 桶归 RunLedger) | 无(零随机全确定) |
| save_system(D3,Alpha;iter27 已升格 autoload「SaveManager」) | 存档格式与版本比较 | (契约规范源:../../gdd/systems/表现与支撑/存档序列化.md——契约锚:SCHEMA_VERSION + master_seed + 各流 scope 计数器快照,须在无正在执行中的 open_stream 实例时切出) |
ConfigDB、RngService 只读计数器 | FileAccess——LOW |
| settings/localization(D6,愿景) | 设置项、翻译数据 | (契约规范源:../../gdd/systems/表现与支撑/设置与本地化.md) |
ConfigDB | 无 |
核心层
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|---|---|---|---|---|
| board_generator(A1) | 生成算法(五阶段管线)、BoardGenTable 回填、生成期指标集、合法性谓词(clearable / R₀≠S / min_safe)、可推理率度量(metric_version);生成姿态 = MVP 同步生成 + 加载幕(切片实证 10×10/12×12 同步可接受,WorkerThread 留扩展) | generate(L, D, rng) -> Board;度量独立入口×3(推理器 / F3 度量 / 合法性谓词——独立纯函数、同一实现) |
ConfigDB(BoardGenTable/VariationTable);board_gen 流(一次 open_stream = 一张图);dig_ap_cost 只读 | 无 |
| minesweeper_rules(A2) | 棋盘状态(已开集 O / 封印集 G / 小人位)、三事件面、批次仲裁、install 四不变式 | install_board(board);settle_batch(intents)(唯一提交入口);查询只读面(current_board / hero_pos / is_revealed / has_seal 等);compute_move_path(cell) 只读;retire_board();三源拒绝(board_face / resource_face / phase)+ sub_reason 封闭枚举 |
A1 产物(Board class_name 数据契约);A3 try_spend / last_round_end / 相位 | 无(零表读取、零 UI——切片实证) |
| unit_container(B2) | hero/enemy 单位实例(hp/atk/实例池:池快照+冷却+摇定动作+保底计数)、行值快照 | spawn / query_alive / rollable_skills / special_skills / set_pending_action / pending_action / basic_streak / commit_action / tick_cooldowns / apply_damage / heal / default_target / check_skill_unlocks / despawn_all(2026-09-16 敌人技能池批:query_beat/query_attack/advance 随行为环退役) | ConfigDB(EnemyTable/SkillTable/HeroTable) | 无 |
| reward_economy(B4) | 格面资源身份映射(install 期预分配、Ready 只读、换图映射消亡)、极性路由字典面((类型, 极性)→ 字典行查询;路由执行归 B1 授予段)、F6 当量供给投影 | 封闭 API:roll_board / query_identity / query_full_snapshot / grant / grant_clear / retire_mapping / polarity_row / phase / weighted_pick;另有 is_mapped 静默布尔投影(批量工具用) | ConfigDB(RewardTable);effect_engine(事件发射 dispatch——上层消费基础层);reward_roll 流(scope = 每次 install 批) | 无 |
| helper_items(A5,切片已实装秘宝域) | HelperItemTable、探测显影语义 | (契约规范源:../../gdd/systems/跨局循环/秘宝.md——桥接位:A2 查询接口 + A4 counter_item_ids) |
A2 / A4 / B4 | 无 |
功能层
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|---|---|---|---|---|
| battle_orchestrator(B1) | 段序骨架(七段结构冻结)、轮 facts 缓冲、可回放步骤流、明细行协议(基础行型+扩展行两层 + 字段分层,词表以 owner「明细流水」节为准)、条款③⑤闭合对账、战斗域全部跨系统调用权、效果引擎宿主(每战 rebuild;round/battle 桶为编排器自有字典、经 EffectContext 引用挂载)+ 树规则挂点施加面(posture 窗/sense 限次/守侧 seal_missed 发射/聚乘算入账前) | begin_battle(encounter);窗口/刷新意图提交面(扮演 D1);level_clear();步骤流(输出契约) |
B2/B3/B4 全调用面(唯一调用方=B1 域文件集:battle_orchestrator.gd + settlement/ 五段段类 + damage_controller);A3 request_refresh 代理 + 回发;A2 install/retire + 三事件订阅;A1 generate(attempt 非 scope 事件);D2 SettlementTable + set_reload_gate | 无(零随机、禁 await——切片 88 冒烟实证可回放) |
| damage_controller(B1 域·伤害单据管线) | 伤害单据唯一兑现管线(单据九栏目声明→分量掷点/克制修正/伤害下限归一→明细行发射;双方同规) | 兑付入口(编排侧开单)+ fx 揭示回调注入位 | B2 单位实例(单据目标传入);B1 注入(EffectContext 引用束与编排回调) | 无 |
| settlement/ 五段段类(B1 域·结算段件) | B1 每轮结算序列的五段逻辑件(授予/增益减益/战斗/衰减/判定——细则见下「战斗域装配现状」节) | 段处理入口(B1 接线调用);可直接 new() 单测 |
B2/B3/B4 兑付面与 B1 轮 facts 缓冲(各段按职责) | 无 |
| level_runner(C1-lite,切片已建) | 关卡域生命周期(节点链推进、共享 B4 + HP 携带、关卡末 level_clear) | 节点推进接口;LevelTable(level.tres——节点 enum {battle,reward,rest,boss}、末节点必须 Boss、ConfigDB 跨表校验⑧) |
B1(直构 BattleOrchestrator 接线战斗)、ConfigDB LevelTable | 无 |
| run_structure(C2) | 冒险/关卡序列、失败重开、master_seed 唯一接线方 | (契约规范源:../../gdd/systems/冒险循环/冒险结构.md) |
RngService.set_master_seed、C3/D2 | 无 |
| difficulty(C3) | DifficultyTable 回填、全部曲线数值调参所有权、战斗期望表(切片 monte_carlo 为工具原型) | 调参输出(经 D2 R1 解析/编排器传递,禁反向调用生成) | ConfigDB、B1 对账输出(调参约束清单)、A1 报告 C | 无 |
| meta_progression(C4,Alpha) | MetaTable、钥石账本、天赋树域(MetaTreeTable 12 节点 v0.8——Fork 一节点双态/row 字段退役/RULE_KEYS 六键/彩蛋特化觉醒,迭代 21 T1 换代)+ 同调位槽位判定(树点亮数单源——T4 槽位收编) | tree_can_buy/tree_buy/tree_buy_fork/tree_toggle_fork(写口唯一)、hero_override 注入(树淬炼 flat+锻造路线加值位预留 0)、tree_rule_keys | D3、C2、ConfigDB | 无 |
战斗域装配现状(迭代 27——2026-10-17 用户裁写入)
- 结算五段:B1 编排器的每轮结算序列拆为
game/core/settlement/五个段类——GrantSegment(①授予段,含封印判定与 counter/grant 助手单点)→ AuraSegment(②增益/减益段)→ CombatSegment(③战斗段)→ DecaySegment(④衰减段)→ VerdictSegment(⑤判定段,返回裁定,终局早退语义留 B1)。段序骨架冻结于SettlementTable.segment_order语义,B1 退为段序编排+接线;段类可直接new()单测(settle_segments_test在役)。 - RunLedger 四账:
game/core/run_ledger.gd单类持四本共享账——同调充能账/真视使用计数/冒险域计数器/统一冒险加算区。所有权:AdventureRunner 开局构造、全程唯一宿主;LevelRunner 经set_run_ledger下传装配 encounter;战斗侧(B1)经encounter["ledger"]拿引用、只走 read/append 原语族。审计 P1-4「共享可变字典跨三层三处可写」由「函数签名上不可见的共享引用」换成签名可见的显式类。冒险桶计数器无导出/灌入时点:EffectContext 持run_ledger.adventure_counters的同一字典引用,引擎静态计数口就地直写,跨战持久随 RunLedger 生灭(2026-10-21 迭代 32 卡②无状态化写入)。
呈现层
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|---|---|---|---|---|
| D1 HUD(呈现面拆分持续换代:组合根 main.gd + 三屏壳(MenuScreen/CampScreen/AdventureScreen)+ views/ 视图单元(现行承载面见「呈现层装配与会话生命周期」节;早期 9 单元清单与 LevelStripView 已随场景换代退役);营地覆盖层=四柜台并排〔树淬炼主界面/锻造工坊·秘宝匣钥匙门/图鉴常开——迭代 21 T6 程序占位重排〕) | 全部 Control/CanvasLayer(例外:BoardView 棋盘本体与 BattleStageView 站桩本体 = Control 壳 + SubViewportContainer + SubViewport + Node2D 世界〔BoardWorld/CellUnit;StageWorld/StandeeBody——B 区 slot_row 伴随件留壳层〕,探针契约面不变——棋盘 Node2D 迁移批 Phase A 2026-09-23 / 战斗舞台 Phase B 2026-09-26)、输入→意图翻译(唯一提交路径 = settle_batch,不直调 A3)、呈现义务状态记录(A2×6 / B2×4 / B3×4 / B4×5 / B1×3) | 视图单元接口(信号外发、setter 只读注入) | A2 compute_move_path / ActionOutcome;A3 ap/rap;B1 步骤流行协议(数据源);ConfigDB display_name | MEDIUM:Control / CanvasLayer / draw_* / InputEvent / RichTextLabel——对照 breaking-changes.md 4.5–4.7 条目(CanvasItem 线条无抗锯齿羽化、设备 ID 常量、RichTextLabel 图片参数两轮变化) |
| 组合根拆件(呈现侧写口子件:curio_interact_controller / camp_shop_presenter / treasure_interact_controller) | 代组合根执行核心写调用(冒险节点后续推进/营地购买与刷新/道具使用——依赖与回调由 main 构造注入) | 各拆件的写入口(仅组合根装配面可达;视图零直连) | 构造注入的核心写引用(推进/商店/道具各域——详见各拆件头注) | 无 |
| battle_presentation(B5,垂直切片后) | 结算动画 / 伤害数字 / 战斗舞台 | (契约规范源:../../gdd/systems/战斗循环/战斗表现.md——前置「战斗表现美术测试」锁双舞台陷阱) |
B1 步骤流(回放脚本源)、D1 | MEDIUM:AnimationPlayer(String→StringName 变更)/ Tween |
| audio(D4,Alpha) | 音频挂点 | (挂点 = B1 明细行类型流;负反馈聚合——单结算至多一次) | B1 流水 | AudioStreamPlayer(4.7 area_mask 默认 1→0 注意) |
| tutorial(D5,Alpha) | 教学条目 | (口径来源:A2/A3/B3/B1 各教学条目) | 各上游 | 无 |
依赖单向性:上层可消费下层,禁止反向(C3 禁调用 A1 生成、D1 不直调 A3、A2/B3/B4 零相互直调)。全项目唯一回边 = A2 事件订阅面。
呈现层装配与会话生命周期(迭代 27/28 完成反哺——2026-10-17 用户裁按推荐案写入)
三屏壳与组合根句柄面
- 呈现场景拆为三屏壳:MenuScreen(开始菜单屏)/CampScreen(营地屏)/AdventureScreen(冒险屏——内含关卡地图与战斗两容器)。
- 屏成员经组合根 main.gd 一级句柄暴露(探针挂载假设
main.X路径零迁移);局态一律住 RunScope 节点,禁在屏/视图侧持有局态引用。 - 组合根拆件=组合根构造注入、代组合根执行核心写调用的呈现侧子件(现行三件:curio_interact_controller/camp_shop_presenter/treasure_interact_controller——冒险节点后续推进、营地购买与刷新、道具使用)。视图禁直连拆件;核心写调用的可达路径仍是「视图→信号→组合根(含拆件)→核心」,依赖规则与组合根单点装配不变。成员见「模块归属·呈现层」表。
视觉层装配合同
- 树序 = 登记序 = z 序,同源派生;层序唯一事实源 =
main.gd的LAYER_CONTRACT常量表(现行 18 项,kind 五类:shell=屏壳〔成员随壳不占独立树位〕/modal=模态层〔入登记册,tags 随登记〕/state=全屏态/node=非视觉节点/float=不注册 ModalStack 的最顶浮层〔任何 UI 打开都不遮挡它〕)。 - 全仓唯一落位口 =
_apply_layer_contract()(装配尾统一排序+登记);散落move_child由冒烟 V1d 源码断言判红;改层序只改合同表。 - 具体层清单不复制进本文(双写失同步禁令)——查现行 18 项直接读
main.gd。
会话生命周期(RunScope)
run_scope.gd= 纯状态承载 Node:零信号连接、零视图构建、零核心写调用(连接只在组合根,组合根经run_scope.X读写)。- 会话更替机制:
_begin_session()新建会话节点挂树、旧会话节点整节点queue_free()——无独立收束函数,跨局字段清理靠节点释放机制(原手工复位清单随其消亡,新增跨局字段零新增泄漏点);_ready即建闲时会话,run_scope永非 null。 - 存活性矩阵(九阶段 × 五引用面,2026-10-17 用户裁认账阶段划分;执行判据=冒烟 V3a–V3i。计划书原十阶段中「开局停点」与「地图选路」在现行流程同为关卡画面停点态、无可观测中间态,合并为一处断言):
| 阶段 | run_scope | adventure | runner | settlement |
|---|---|---|---|---|
| ① 闲时 | 在树(闲时会话) | null | null | null |
| ② 开局停点 | 在树 | alive | alive | null |
| ③ 战斗中 | 在树 | alive | alive | alive |
| ④ 结算后(胜利停点)/⑤ 选路页 | 在树 | alive | alive | both |
| ⑥ 终局面 | 在树 | alive | alive | null |
| ⑦ 回菜单收束 | 新闲时会话即刻在树(旧会话已释放——无真空窗) | null | null | null |
| ⑧ 各模态开合后(设置/生涯/营地/调试) | 闲时会话零扰动 | null | null | null |
| ⑨ 两连局+续玩断点 | 换全新会话在树 | alive | both | both |
- 三态记号沿用冒烟参数:alive=应有实例、null=必须缺位(实测非空判红)、both=按分支可空可活(如胜停点后走向选路或直接终局)。对象有值但已失效一律判「悬挂」红。
- 第五引用面=四持句柄件(
_treasure_ui/_bonus/_camp_pres/_modal_flow,另有_row_pacer):其会话取值 Callable 与run_scope成员逐面同源比对(回调悬挂=两值不等即红),会话更替零残留由矩阵每阶段顺带铁证。
模态编排(ModalFlow/ModalStack)
modal_flow.gd= 模态编排纯逻辑类(依赖仅 ModalStack + 查询 Callable,可直接new()单测):开合编排(遮挡记账单口 + T17 演播后排窗挂起)/棋盘输入锁谓词/角标置灰谓词三职责。- 互斥排除语义随层登记(
register(node, tags)):debug_overlay=["non_locking"]、level_screen=["screen_state"],其余层零标签——原调用点排除式条件拼装已消亡。
测试与质量域
定位:本节为测试域(本地闸、探针、静态扫描等横切关注点)的事实源。仓库无远端、无 CI——本地闸是唯一验收门禁,判定严密性即全仓质量下限。
模块归属
| 模块 | 载体 | 独占职责 | 对外暴露 | 判定口径 |
|---|---|---|---|---|
| run_smoke(冒烟测试运行器) | tools/run_smoke.py |
冒烟测试总入口与判定权:headless 以项目运行目标拉起 res://tests/smoke_boot.tscn(极小启动场景——autoload 在位、配置表全载、主屏实例化,零逻辑判定)+ 三闸判定 |
进程退出码(0=PASS / 1=FAIL) | 三闸齐备、判定无洞:①退出码 = 0;②摘要行「[smoke] 摘要:N 项检查,0 项失败」在案且失败数为 0;③输出扫 SCRIPT ERROR / Parse Error 标记行。外部 wall-clock 超时在位(超时 = FAIL) |
| run_system_test(系统测试运行器) | tools/run_system_test.py |
系统测试总入口:headless 跑真实玩法路径断言面(宿主=res://tests/system_test.gd)+ 三闸判定(口径同 run_smoke,摘要行兼容两种宿主格式) |
进程退出码(0=PASS / 1=FAIL) | 三闸齐备(同 run_smoke:退出码/摘要失败数/脚本错误扫描;wall-clock 超时在位) |
| run_all(单元与集成测试) | game/tests/run_all.gd |
40 套统一入口(39 单元+1 集成,2026-10-22 实数):套件 manifest 逐条「套件 → 期望退出码」,致命类 expect=1 独立子进程实跑;negative 字段标负面套件(仅豁免错误扫描一闸) |
逐套件结果 + 汇总退出码(任一套件失败 quit(1)) | 套件级退出码协议在位;三硬闸齐备(入口内扫子套件输出 + 编排层扫 unit.log;Kit.finish 零断言返回专用码 2)。子进程输出须经系统命令解释器重定向落盘再读——OS.execute 的输出管道在本机恒空 |
| probe_gate(场景探针) | tools/probe_gate.sh |
headless 场景探针段编排:默认段 ui_input_probe / ui_struct_probe / layout_probe / ui_contrast_probe / screen_flow_probe(屏壳切换),--click 加跑 ui_click_probe,--full 加跑 ui_probe / ui_tune_probe / t17_defer_probe / fx_probe;孤儿 Godot 预清 + 批末残留清点(必须 0) |
段级 FAIL 输出 + 汇总退出码 | 每段 timeout 守卫在位(挂死 124/137 = FAIL,不静默);判定统一走 verdict 函数——退出码为唯一权威判据,PASS 串降级为附加判据,逐段跑 tools/error_scan.py |
| render_gate(视觉 golden) | tools/render_gate.sh |
窗口化渲染闸:①shot_probe 七屏截图 → shot_checker A-D 语义断言;②fx_shot_probe / board_shot_probe 取证(超时/零字节/文件缺失任一 = FAIL);③棋盘 golden 逐像素容差比对(差 ≤16 / changed ≤2%,provisional)+ 菜单 golden;④批末孤儿残留清零 | 段级 FAIL 输出 + 汇总退出码 | 查退出码在位(每段 timeout 守卫 + 退出码/取证文件双检);SCRIPT ERROR 扫描缺失;断言数下限不适用(判定主体 = golden 容差与取证文件存在性,非断言计数) |
| static_scan(静态扫描域) | game/tests/static_scan.sh |
静态扫描域 S1–S10 可执行载体(grep 规则 + tools/audit_type_hints.py〔S9〕+ tools/audit_file_headers.py〔S10〕) |
fail 聚合退出码(任一硬失败规则命中即 exit 1) | 查退出码在位;SCRIPT ERROR 扫描与断言数下限不适用(逐规则命中即红,无运行时错误面与断言计数);S3 现为 warning 级、不参与 fail 判定(见下表) |
改动域划分(2026-10-17 用户裁「代码批只跑代码闸、文档批只跑文档闸」)
| 域 | 闸 | 本批改动落在这些路径即属该域 |
|---|---|---|
| 代码域 | run_smoke、run_system_test、run_all、probe_gate --click、probe_gate --full、render_gate、static_scan、回放确定性对拍(条件件) |
唯一触发=game/(游戏工程代码、测试、探针、场景、数据表)。2026-10-18 用户裁「跨领域执法禁绝」(提交 7bdf53e3)后,原 tools/、artwork/ 两前缀不再把改动拉进代码域 |
| 文档域 | gdd_lint、doc_link_audit、doc_term_audit、流水线闸 | 一切非 game/ 的路径:design/、根规则文件(AGENTS.md/roadmap.md/待办清单.md/体验验证清单.md)、tools/ 工具脚本、.zcode/ 配置、sim-data/、reports/ |
| 两域都含 | repo_structure_audit(熵增闸:顶层目录/根文件/图像白名单/退役路径/design 子目录五查——文档批新增或挪动 .md 同样会绊它;纯文本扫描秒级) |
— |
口径三条:域划分的唯一出处是 tools/run_all_gates.sh(--code/--docs/不带参数=全量),本表是它的现状登记、不是第二份清单;改闸件本身或一次改动跨两域 → 跑全量档(§6.2 共享件例外);合回闸按 merge diff 路径推出应验的域,再校验回执的 domain 字段与新增红。代码域跑前先过素材齐盘预检——game/assets/art/** 与一切 *.import 边车都不入 git(2026-09-29 裁定),worktree 冷检出必空盘,空盘态冒烟 V1 成片假红、渲染闸更是一段 golden 都不比。
三条判定硬闸现行状态
| 硬闸 | run_smoke | run_system_test | run_all | probe_gate | render_gate | static_scan |
|---|---|---|---|---|---|---|
| 退出码优先 | 已落实(闸①) | 已落实(闸①,口径同 run_smoke) | 已落实(套件 manifest expect 协议) | 已落实(verdict 函数逐段判退出码,PASS 串不作判据) |
已落实(段级退出码 + 取证双检) | 已落实(fail 聚合退出) |
| SCRIPT ERROR 扫描 | 已落实(闸③,外部扫描——GDScript 无脚本错误陷阱 API,闸设在外部包装) | 已落实(闸③,标记清单与 run_smoke 同源) | 已落实(入口内扫子套件输出;子进程的 stdout/stderr 须先落盘——OS.execute 管道在本机恒空) |
已落实(逐探针段 tools/error_scan.py,标记与 run_smoke 同源) |
缺失(本批未收——判定主体是 golden 容差与取证存在性;登记待办清单) | 不适用(静态域无运行时错误面) |
| 断言数下限 | 无独立下限(闸②摘要行必须在案,防「跑一半仍 PASS」;脚本错误吞断言路径由闸③兜住) | 同 run_smoke(过渡期宿主摘要行必须在案) | 已落实(Kit.finish 零断言返回专用退出码 2——与「断言失败=1」区分,防致命类套件的 expect 协议放过) |
已落实(退出码 0 但无该探针签名标记亦判红——防静默退出) | 不适用(golden 容差 + 取证存在性判定) | 不适用(逐规则命中判定;另有扫描面为空即判红的零命中自检) |
背景事实(run_smoke 头注在案):GDScript 运行时脚本错误不改进程退出码、不计入冒烟失败数、且静默中断所在函数剩余断言——2026-09-19 状态记录 83 实证「309 项 0 失败」实为断言未跑全。这是 SCRIPT ERROR 扫描必须存在于判定层的原因。
静态扫描域 S1–S8 承接清单
静态扫描域规则(2026-09-12 立,沿革见 git commit log;下表为现行事实登记):
| # | 规则 | 状态 |
|---|---|---|
| S1 | 玩法代码禁 randomize()、自建 RandomNumberGenerator(D2 Rule 5) |
在位(硬失败;扫描面 game/core + game/presentation) |
| S2 | 禁全局随机函数 randi() / randf() / randf_range()——全局 RNG 绕开 RngService(specialist 补登) |
在位(与 S1 同段硬失败;实例方法 .randi() 排除、rng-seed-exempt 豁免注记在案) |
| S3 | core/ 禁 ConfigDB 外 data 表加载(load( / preload( / ResourceLoader.load;schema class_name 直引豁免)(D2 Rule 2) |
在位(warning 级——class_name 直引误报需人工复核;路径已由裸 core 修正为 game/core,此前恒零命中静默空转;豁免 config_db.gd 自身=数值单一事实源的正主) |
| S4 | core/ 禁 extends Control/Node2D、禁 .tscn preload(D2 Rule 7) |
在位(硬失败) |
| S5 | core/ 禁裸引用 autoload 全局标识符(ConfigDB / RngService 直接写 = --script 模式 parse error)——构造注入 only(specialist 升格) |
在位(硬失败;形态=标识符后紧跟 . 的成员访问,排除注释行与字符串字面量) |
| S6 | core↔core 信号连接只许方法 Callable(禁 lambda 捕获 self);发射者禁持有订阅者反向引用 | 在位(2026-10-25 落闸:内联 lambda 禁令机器闸——同行与跨行两形态、豁免注记 s6-signal-exempt、盘面零存量;「发射者禁反向引用」句静态判据不成熟,归人工评审面承接、不造弱判据) |
| S7 | B1 编排唯一性:B2/B3/B4 API 符号命中文件 ⊆ B1 文件集;A2/B3/B4 零相互直调(B1 AC-43) | 在位(2026-10-25 落闸:符号清单×B1 域文件集,族内自调用豁免、豁免注记 s7-b1-exempt、缺位自检;全符号形态盘面零存量) |
| S8 | 结算路径 await 零命中(B1 结算/编排文件集);字面量扫描 = warning 级 + 人工三要素复核(D2 AC-14 口径) |
在位(2026-10-25 落闸:B1 域文件集 await 零命中,文件集缺位自检、排除注释与字符串;盘面零存量。本行后半句「字面量扫描=warning 级+人工三要素复核」为独立子项、仍归人工面) |
域外扩充两件(均硬失败在位):S9 类型闸(tools/audit_type_hints.py,迭代 27 T5——产品码无类型容器/有值返回缺类型/参数缺类型);S10 文件头闸(tools/audit_file_headers.py——头注 ≤8 行 + 日期/变更叙事黑名单)。
三层承载与判定原则
测试分标准四级+UI 探针(2026-10-22 用户裁,测试术语与层级重构批),各有在册承载与入闸方式(细目见 game/tests/README.md):
| 层 | 判什么 | 承载 | 入闸 |
|---|---|---|---|
| 冒烟测试 | 这版活着吗(零逻辑判定) | game/tests/smoke_boot.tscn/.gd |
run_smoke.py(闸 00) |
| 单元测试 | 最单元的逻辑代码对不对 | game/tests/unit/ |
run_all.gd(闸 02) |
| 集成测试 | 跨系统闭环对不对 | game/tests/integration/ |
同上(同一入口同一协议) |
| 系统测试 | 真实玩法路径断言面 | game/tests/system_test.gd |
run_system_test.py(闸 01) |
| UI 探针+渲染 golden | 场景切换与观感 | game/probe/*.tscn 探针 |
probe_gate.sh(闸 03/04)、render_gate.sh(闸 05) |
判定原则:验收不能只是「跑一遍没崩」。三硬闸(退出码/脚本错误扫描/断言数下限)是判定的底线,
缺一即判定有洞;「日志里写着 PASS」不作判据。另有两类静默失效必须机制性防范——规则扫描面为空
(路径写错即恒零命中恒绿)与子进程输出丢失(本机 OS.execute 管道恒空),两者都以显式自检拦住。
依赖约束
测试域禁止反向依赖呈现层具体实现。五闸及其调用的探针场景、审计脚本只允许依赖两类边界:
- autoload 边界——ConfigDB / RngService 的公开面(--script 模式不加载 autoload 且不注册全局标识符,测试文件自带显式实例化夹具);
- 场景契约——探针场景的信号外发面与视图单元接口(信号外发、setter 只读注入),禁直引呈现层实现内部(如 UiKit 工厂内部状态、BoardView 绘制细节)。
测试域是所有层的消费方,进入方式限于上述两类边界;除此之外的依赖方向一律与「模块归属」节依赖单向性同规。
事实源声明
本节为测试域(测试载体、判定口径、静态扫描域)的事实源。新增违规案例仍须先补 static_scan 规则再修码(code-conventions 缺陷-规范对照表纪律)。
数据流
1. 帧更新路径(2D 回合制:无逐帧玩法逻辑)
Input(鼠标)→ D1 输入翻译 → 意图对象 → A2.settle_batch(唯一提交入口)
→ A3.try_spend(原子扣减)→ A2 棋盘效果(挖/连锁/封印/移动)→ 三事件外发
→ [棋盘渲染:D1 BoardView 按事件增量重绘;无事件帧 = 静态 + 动效]
→ 轮次结束 → A3 Waiting → B1 结算编排(段序七段)→ 明细步骤流 → D1 结算屏逐行呈现
- 回合制下每帧只做:输入采样、呈现刷新、动效推进——玩法状态只在意图事务内变更(单意图帧输入收集:stop 点击终结当帧)。
- 无跨线程玩法数据流(Godot 主线程假设,D2 EC13);A1 生成若引入 WorkerThread,join 必须先于任何快照切出(既定约束)。
2. 事件/信号路径(系统间通信,无紧耦合)
A2 ──cell_revealed / flag_judged / round_end(棋盘路径)──▶ B1(轮 facts 缓冲)
A3 ──round_end(stopped 直发,payload 同构)──────────────▶ B1
B1 ──notify_settlement_done(next_round_mode) / notify_combat_end──▶ A3
B1 ──apply_effect / apply_damage / grant / 伤害单据 submit…──▶ B3/B2/B4(唯一调用方;段内伤害序=主角先手→逐敌还手→地图账殿后〔案C 2026-10-06〕)
B1 ──install_board / retire_board──▶ A2 B1 ──generate(L,D)──▶ A1
D1 ◀──呈现数据源:A2 事件流 / B1 步骤流 / A3 ap-rap / ConfigDB display_name
- 事件载体(已定):组合根直连信号接线 + B1 Waiting 相位触发(不依赖事件到达序);autoload 全局事件总线已否决(2026-09-12,沿革见 git 历史)——单线程回合制沿用组合根直连(KISS)。
- 事件规范序:A2 发射序 = 触发格 BFS、8 邻行主序;事件序契约
flag_judged<round_end全路径统一。 - 呈现层订阅禁令(切片缺陷②教训固化):呈现层永不直接订阅 排雷玩法/行动经济 的事件流,只订 战斗结算 步骤流与
level_runner——核心事件形态变化不得直接冲击界面。
3. 存档/读档路径(MVP 无存档;契约已锁)
- MVP 无元进度持久化(C4/D3 归 Alpha)。已锁契约:续玩/复盘快照 = master_seed + 各流 scope 计数器 + 意图序列 + 窗口选择序列;快照切出须发生在无正在执行中的
open_stream实例时(scope 事件边界外——B1 编排保证:切点 = board install 边界)。 - 可回放性已实证:切片冒烟同种子双跑步骤流逐行相同(B1 AC-33 前身)。
- D3 Alpha 期按此契约设计格式;SCHEMA_VERSION 高版本拒读。
4. 打包与字体(CJK 随包发行)
CJK 字体随包发行并设为 theme 默认字体——运行时默认字体无中文字形。此项是 HUD框架 正式化的硬性前置,同时进导出 checklist 核对项。
4. 初始化顺序
进程启动
→ autoload 实例化:ConfigDB → RngService → SaveManager → MetaProgression(顺序固定;战斗编排器等核心类为普通类、由组合根按局实例化)
→ ConfigDB._ready():load_tables 加载 + 校验(致命通道;失败 = 构建中止 + 错误清单)
→ 主场景(D1 组合根)装配视图单元 + 信号接线
→ C2 begin_run:RngService.set_master_seed()(唯一接线方;两流计数器全零前提)
→ B1.begin_battle(encounter):set_reload_gate(true) → B3 开域 → B2 spawn → A2 install_board(A1.generate) + B4 roll_board(恰一次)→ A3 notify_round_start
→ 挖掘循环 …… → battle_over 清理序列 → set_reload_gate(false)
→ 关卡末:通关结算(钥石/GP/专长 level_clear 渠道——现行语义归 冒险结构 GDD;原 clear_inventory 随库存轴下线退役 2026-09-15)
启动后置条件(2026-10-17 用户裁入册——迭代 28 以冒烟 V2a–V2f 共 11 条断言把「启动完成后玩家该看到什么」成文;执行判据事实源在 game/tests/system_test.gd):
- ConfigDB 就绪且表已载(
is_ready+ hero 表在座)。 - 系统设置已落引擎态——Master 音量 mute/volume_db = settings_store 现值;减动效开关 =
UiKit.motion_scale。 - 启动态菜单可见(boot 后自树顶向下第一个可见内容层 = 开始层——菜单被冒险屏盖住即红)。
- 续玩钮可见态恒等于断点在档态(双向:无断点隐藏/有断点可见/清断点回隐;boot 路径与刷新单口同源)。
- 闲时会话已在树(
run_scope非空、非冒险会话、在树——永非 null 契约的启动侧证明)。 - 调试浮窗 boot 不自动开(菜单优先,2026-10-16 用户令)+ 调试入口全局浮层角标 boot 可见。
API 边界
完整 API 面(含封闭枚举负空间、布尔受理口径、输入×相位矩阵)以各 GDD AC 前言为规范源——本节列边界契约与不变式,实现须与 GDD 逐字一致;冲突时以 GDD 为准并走接口漂移修订。
| 边界 | 契约要点 | 调用方必须遵守的不变式 | 模块保证 |
|---|---|---|---|
| D1 → A2 | 意图经 settle_batch(intents) 提交;不直调 A3 |
单意图帧收集;stop 经批次委托 | 语义序仲裁 + voided 零副作用 |
| A2 → A3 | 挖/插/拔 = 先棋盘面判定后 try_spend;A2 不可自行扣减 |
相位判定两侧一致(同一矩阵) | 原子事务(余量+扣减+仲裁一体) |
| A2 → 下游 | 只外发三事件,payload 字段封闭(digit 恒真透传 / reward_eligible / variant_ids) | 增删事件 = 接口漂移 | 发射面封闭 + 规范序 |
| B1 → B2/B3/B4 | 全调用面集中 B1;调用序钉死(按摇定技能行兑现→apply_damage→commit_action;先兑付后衰减;段内伤害序=主角先手→逐敌还手→地图账殿后〔案C 2026-10-06〕) | 禁第二调用方(静态扫描域:API 符号命中文件 ⊆ B1 文件集) | 恰一次编排纪律(roll_board/decay/清理全序) |
| B1 ↔ A3 | 编排期代理 request_refresh(玩家意图,禁 RAP 满自动刷);回发 next_round_mode/battle_over |
stopped/ap_exhausted 未刷新回发 new_board = 违约 fail-fast | 刷新受理契约(同 Waiting 多次合法) |
| 各系统 → D2 | ConfigDB 类型化属性单点读取 | 禁绕过 ConfigDB load 表、禁缓存副本、禁玩法数值字面量、禁 randomize()/自建 RNG | 校验双通道 + fail-fast 致命 |
| A1 → A2 | Board 产物 class_name 数据契约 | install 四不变式校验(violation = 拒绝 + 五类诊断枚举) | 生成期合法性闸(R₀≠S / clearable / min_safe) |
| A1 ↔ B1 | attempt 边界非 scope 事件;actuals p10 为对账输入(非 target 参数) | 编排不把重试当取号 | 生成期指标集输出(实测可推理率 / 实际雷数与安全格数 / 重试次数 / 降级与非法产物标记) |
| B4 → B3 | buff 类经 B1 调 apply_effect(B4 零跨系统读、零直接接口) | 满层拒绝 = 零兑付 + 明细行(无折算) | 授予时数值快照(抗热重载) |
| B1 → D1 | 步骤流行协议(基础行型+扩展行两层封闭 + 公共字段 type/source_class/origin_cell/round_index/display_name/value/highlight? + 特有字段 target/effect_id/pool_value) | 无来源行 = 断言失败;呈现侧禁按行序重演 B2 状态机 | 可回放步骤流(同种子逐行相同) |
引擎类型核验注记:接口使用的引擎类型 = Resource / .tres(D2 全表)、RefCounted(容器类)、Signal/Callable(事件载体)、Control/CanvasLayer/Drawing(D1)、SceneTree headless 协议(测试)——均属 4.x 基线稳定面;4.7 Control 域增量(offset_transform_* 等)已在 breaking-changes.md 登记,D1 采纳前对照核实。
架构原则
- 核心层纯逻辑、headless 完整可跑——核心层/功能层玩法逻辑零 Control/场景引用、零 UI 依赖;
--headless --script可跑完整战斗(D2 Rule 7 工程债;切片 88 冒烟实证)。输入是意图对象、输出是事件流/步骤流,D1 与输入设备皆可替换。 - 单一事实源与零字面量——玩法数值只存在于
data/tables/*.tres,经 ConfigDB 类型化单点读取;代码零玩法数值字面量;参数禁止跨系统复制(D2 Rule 1/2)。 - 封闭 RNG 与可回放——玩法代码零随机;一切随机经 RngService 具名封闭流(增流走 P1 评审);同种子 + 同输入序列 ⇒ 事件流/步骤流逐位相同(结算禁 await,B1 承重约束)。
- 编排唯一性与事件面封闭——战斗域跨系统调用权集中 B1(静态扫描承载);A2 三事件面封闭即负空间;每格受理、每雷转化、每次推进、每次衰减各恰一次。
- fail-fast + 零特判——数据错误一律致命中止(错误数值上线比崩溃更伤);API 非法 = 拒绝 + 诊断不静默;变异零运行时分支(行为差异全部由生成端约束保证)。
- 依赖单向 + 组合根模式——层间单向依赖、唯一回边 = A2 事件订阅面;核心写调用唯一发生在组合根;禁上帝对象(切片 1100 行 main.gd 反面案例 → 9 单元拆分)。
- 呈现层契约成文——面向呈现的信号载荷必须有成文 schema;模态覆盖层必须有"打开时遮挡物隐藏"场景级断言;场景级 UI 探针测试为标配(切片缺陷 ①②④⑤ 教训沉淀)。
- 系统无状态——效果引擎这类系统零运行时可变状态:数据由宿主对象持有并随宿主生灭,状态按参数传入系统,系统只做判定(立项判据=2026-10-19 用户会话裁定;落地=迭代 32 卡②,2026-10-21 用户裁写入)。系统实例不持计数器——计数器住桶(round/battle/level/adventure 四桶,EffectContext 引用束),桶住宿主。
未决问题
| ID | Summary | Priority | Resolution Path |
|---|---|---|---|
| QQ-01 | 渲染器选择(Forward+ vs gl_compatibility)与项目窗口基线 | High | 已落定(2026-09-12):gl_compatibility + 1280×800 基座(canvas_items + expand);沿革见 git 历史 |
| QQ-02 | 事件总线载体与 A2 事件捕获测试 API | High | 已落定(2026-09-12):组合根直连 signal + Waiting 相位触发;autoload 全局总线否决 |
| QQ-03 | gdUnit4 是否引入并迁移冒烟用例 | Medium | 已落定:deferred(现行双载体承载;D2 OQ1 关闭) |
| QQ-04 | 轮内刷新数值连锁(清图支配性条款⑤ / 真人刷图行为获取期望)重算 | Medium | playtest 实测 |
| QQ-05 | 战斗末可选类"j==0 补发 1 件"兜底是否采纳(切片遗留待办) | Medium | playtest + B4 GDD 修订批 |
| QQ-06 | 可选类退出格子池后 buff 频率被动上升(44%→59%)的难度对冲杠杆(敌 HP / 权重 / 幅度) | High | C3 调参 + 切片数据复测 |
| QQ-07 | 标错惩罚(A2 OQ1:候选敌方伏击+1;hit=false 无去重的不对称裁决) | Medium | 原型小补丁实测会话(可与 v3 终验合并) |
| QQ-08 | B5 双舞台陷阱(战斗发生在棋盘上还是独立场景) | Low(B5 前) | 战斗表现美术测试后裁决 |
| QQ-09 | C3 消费 B1 对账输出的事实依赖回写 design/gdd/02-系统清单.md |
Low | C3 GDD 定稿时 |
| QQ-10 | .claude/docs/director-gates.md 缺失(TD-ARCHITECTURE/LP-FEASIBILITY 判据无载体) |
Low | 补建 gate 定义文件或维持 solo/lean 模式约定 |
| QQ-11 | A1 生成性能姿态(F2c 常数 C 定稿;切片实证 10×10/12×12 同步生成可接受,WorkerThread 留扩展) | Medium | A1 GDD 修订批 |
| QQ-12 | 零伤害死局跨字段/跨表护栏落点(B2 OQ9;推荐 D2 跨表校验——切片 LevelTable 校验⑧先例) | Medium | D2 校验设计批 |
| QQ-13 | A1 EC5 运行期熔断(连续降级确定性回退已知好种子) | Low | A1 GDD 修订批 |
| QQ-14 | A5 探测显影接口 / D3 存档格式(RNG 快照契约已在案,格式归 Alpha) | Low | 秘宝域正式化 / D3 Alpha 设计批 |