32 KiB
Dungeon Sweeper — 总体架构文档
文档状态
- 版本:2.0(收窄为约束面形态——分层/模块归属/数据流/API 边界;实现现状归代码与代码头注,实现历史归 git commit log,闸清单与判定口径归
game/tests/README.md,见 doc-conventions「架构事实唯一源」行) - 引擎:Godot 4.7.2-stable(GDScript 单语言;2026-09-07 锁定)
- 评审模式:solo(
review-mode.txt——门禁按 solo 跳过) - 覆盖 GDD:现行全集(根索引=
design/gdd/02-系统清单.md,文档树构成以根索引为准) - 事实源地位:本文是架构约束的唯一权威(分层/模块归属/数据流/API 边界);写权限=用户专属(agent 与技能只读)
- 实现实证:
game/(完整游戏开发版本;本文分层与所有权经实现验证)。测试层级=冒烟/单元/系统三级+UI 探针与渲染 golden,识别三元组权威=design/engineering/test-conventions.md「测试层三元组」节
引擎知识缺口摘要
- 引擎事实现行事实源=
design/engineering/engine-reference/godot/(VERSION / breaking-changes / deprecated-apis / current-best-practices 四件)——迁移核实结论、语义变化与编码注意一律查那里,本文不重复。 - 渲染器与窗口基座=gl_compatibility + 1280×800;UI/渲染域为引擎风险集中地,采纳引擎增量前对照 engine-reference 核实。
- 写码纪律不变:不确定的 API 一律查
docs.godotengine.org/en/4.7/核实后再用。
系统分层图
20 系统按 design/gdd/02-系统清单.md 依赖分层表映射到标准五层。实现已验证该分层(core/ 纯逻辑零 UI 依赖 headless 可跑、presentation/ 组合根模式)。
┌────────────────────────────────────────────────────────────┐
│ 呈现层 │
│ D1 HUD 与界面框架 (MVP) · B5 战斗表现 │
│ D4 音频 (Beta) · D5 教学引导 (Beta) │
├────────────────────────────────────────────────────────────┤
│ 功能层 │
│ B1 战斗结算编排 (MVP) · C1 关卡节点地图 │
│ 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 | ✅ | LOW |
| C2 冒险结构 | 功能层 | MVP | ✅ | LOW |
| C3 难度曲线 | 功能层 | MVP | ✅ | LOW |
| C4 元进度 | 功能层 | Alpha | ✅ | LOW |
| D1 HUD | 呈现层 | MVP | ❌(UI 层——场景级探针测试承载) | MEDIUM(Control/Input/文本域) |
| B5 战斗表现 | 呈现层 | 切片后立项(未实装,前置战斗表现美术测试) | ❌ | MEDIUM(Animation/Tween/渲染) |
| D4 音频 / D5 教学 | 呈现层 | Beta(与游戏内容无关者一律排 Beta) | 部分 | LOW-MEDIUM |
| D3 存档序列化 | 基础层 | Alpha | ✅ | LOW |
| D6 设置/本地化 | 基础层 | 完整愿景 | ✅ | LOW |
依赖分层与唯一回边:A2 只外发三事件(cell_revealed / flag_judged / round_end),B4/B1 订阅后回调——A2 不依赖任何下游(TD-SYSTEM-BOUNDARY 裁决,全项目唯一允许回边)。
模块归属
命名遵循
design/engineering/code-conventions.md:领域命名、禁 ID 前缀。本表只写约束:模块的职责语句、对外封闭面概述与消费依赖——各件的完整公开方法面、成员与接线明细归代码文件头注(##文档注释)与代码自身承载;文件路径是导航索引。
基础层
| 模块 | 文件 | 独占职责 | 对外封闭面 | 消费依赖 |
|---|---|---|---|---|
| ConfigDB(autoload,D2) | game/core/config_db.gd |
全部玩法数值表唯一加载与持有单点(.tres 经校验后入容器);行族访问器归各 schema 表类(表管自己的行查询),本类只留加载/校验/override/诊断门面,表持有按域收进域容器 Resource |
类型化域容器属性+load_tables / reload / set_reload_gate / diagnostics 族 | 无(基础层顶点) |
| RngService(autoload,D2) | game/core/rng_service.gd |
master_seed 与各封闭流 scope 计数器单点(封闭流词表现值以 RngServiceCore.PURPOSE_TAGS 为准,增流走 P1 评审) |
set_master_seed(唯一调用方 C2)/ open_stream 有状态门面 / derive_at 纯函数 / 只读计数器 | 无 |
| save_system(SaveManager,autoload,D3) | game/core/save_manager.gd |
存档格式与版本比较、序列化接线单点;槽位文件域归 SlotStore、元进度数据归 MetaStateStore | 写盘/读回/槽位管理/断点快照公开面(契约规范源:../../gdd/systems/表现与支撑/存档序列化.md——契约锚:SAVE_FORMAT_VERSION + master_seed + 各流 scope 计数器快照) |
ConfigDB、RngService 只读计数器 |
| SlotStore(D3) | game/core/slot_store.gd |
存档三槽位文件域唯一所有者:槽位挂载与模板、激活与建删、摘要窥视 | 槽位读写原语族+摘要投影 | save_manager(注入路径与模板配置) |
| MetaStateStore(D3) | game/core/meta_state_store.gd |
存档内元进度数据的读写唯一层(数据读写原语,不含业务规则) | 写口原语族+只读投影(消费方经 save.meta_state. 直连) |
save_manager(序列化接线) |
| MetaProgression(autoload,C4) | game/core/meta_progression.gd |
元进度账本服务:钥石收束入账、营地消费定价与解锁判定的纯被动服务,零信号零外发;业务层(数据读写全经 MetaStateStore) | 写口族(天赋树/锻造/同调)+解锁判定与读投影;四个 Autoload 中唯一有跨 Autoload 依赖(ConfigDB/SaveManager) | ConfigDB、SaveManager |
| action_economy(A3) | game/core/action_economy.gd |
AP/RAP 账本、轮次相位机 {Idle, Active, Waiting}、结束仲裁 | 意图与通知布尔面(request_dig / request_stop / request_refresh / notify_* 族)+预授权通道;ap/rap/phase 只读 | ConfigDB、EffectPort、B1 回发 |
| variation(A4) | game/core/variation*.gd |
VariationTable schema 与 F1 候选池门控谓词 | variant_pool(门控三维)/ global_variant_row 访问器 | ConfigDB |
| status_container(B3) | game/core/status_container.gd |
状态实例容器(战斗域生命周期、跨轮跨图延续) | 五 API:notify_battle_start / apply_effect / query_active / decay_round / notify_battle_end | ConfigDB |
| effect_engine | game/core/effect_engine.gd |
零运行时可变状态的全同步解释器(架构原则 8):事件由宿主在明确代码点位显式 dispatch 进件,命中序=装载声明序,不是事件总线/事件循环 | rebuild / dispatch / validate_trigger_row +静态计数口;事件/事实/效果类型/算子四词表封闭+树规则合成订阅六键 | ConfigDB 行集、EffectContext 引用束(四桶由宿主持有) |
| settings/localization(D6,愿景) | — | 设置项、翻译数据 | (契约规范源:../../gdd/systems/表现与支撑/设置与本地化.md) |
ConfigDB |
核心层
| 模块 | 文件 | 独占职责 | 对外封闭面 | 消费依赖 |
|---|---|---|---|---|
| board_generator(A1) | game/core/board_generator.gd |
生成算法(五阶段管线)、合法性谓词(clearable / R₀≠S / min_safe)、可推理率度量;生成姿态=MVP 同步生成+加载幕(WorkerThread 留扩展) | generate(L, D, rng) -> Board;度量独立入口 |
ConfigDB;board_gen 封闭流(一次 open_stream=一张图) |
| minesweeper_rules(A2) | game/core/minesweeper_rules.gd |
棋盘状态(已开集/封印集/小人位)、批次仲裁、install 四不变式 | install_board / settle_batch(唯一提交入口)/ 查询只读面 / preview_reveal 只读预览口 / retire_board;三事件封闭(cell_revealed / flag_judged / round_end,payload 字段封闭) |
A1 Board 契约(class_name 数据契约);A3 try_spend |
| unit_container(B2) | game/core/unit_container.gd |
hero/enemy 单位实例(hp/atk/实例池) | spawn / query_alive / 动作与伤害面 | ConfigDB |
| reward_economy(B4) | game/core/reward_economy.gd |
格面资源身份映射(install 期预分配、换图映射消亡)、极性路由字典面、受理账面(装配期摇号归掷格件 RewardRoller) | 封闭 API:roll_board / query_identity / grant / grant_clear / retire_mapping / polarity_row / phase | ConfigDB;BattleFxHost 偏运合计查询(注入 Callable) |
| helper_items(A5) | game/core/helper_items*.gd |
HelperItemTable、探测显影语义 | (契约规范源:../../gdd/systems/跨局循环/秘宝.md——桥接位:A2 查询接口+A4 counter_item_ids) |
A2 / A4 / B4 |
| CurioDeck(A5) | game/core/curio_deck.gd |
三选一/商店共享令牌池、抽签、cap 库存与专长凭证判定唯一所有者(停点编排与兑付推进留 CurioStop) | draw_candidates 抽签 / consume 族池消耗 / cap_ok / 凭证判定 / stock 只读投影 | ConfigDB;注入 RngServiceCore(reward_pick 封闭流) |
| ShopSession | game/core/shop_session.gd |
关卡商店双模式(legacy 固定三件/pool 共享令牌池)的货架、定价、购买与刷新唯一宿主;账本/钱包经宿主 LevelRunner 注入共享引用 | 货架与定价只读面+写入口;调用方经宿主公开成员 shop 直连 |
ConfigDB;注入 RngServiceCore;pool 模式经注入 Callable 转 CurioDeck |
| HeroStats | game/core/hero_stats.gd |
冒险生命周期主角数值域唯一所有者:生命账与特性持有集、生效公式单点 | 构造注入;单写原语族+只读投影 | ConfigDB;注入 GainJournal(只读);AdventureRunner 创建 |
| GainJournal | game/core/gain_journal.gd |
统一冒险加算区与获得记录唯一所有者(三层结构:记录→明细→四轴汇总) | gain_bonus 单写原语;记录与汇总只读投影 | AdventureRunner 创建,注入各消费方 |
| GpWallet | game/core/gp_wallet.gd |
冒险局内货币唯一所有者(不入存档不入摘要) | gain / spend / clear 单写原语 | AdventureRunner 创建,宿主与商店注入读写 |
| RefreshBank | game/core/refresh_bank.gd |
三选一刷新三源账唯一所有者+GP 付费刷报价公式(零停点态依赖,编排归 CurioStop) | 支出与余量原语+报价公式;断点自交片段(refresh_stock / attune_refresh_y) | ConfigDB;注入 CurioStop 支出路径 |
| AttuneLoadout | game/core/attune_loadout.gd |
装备中的秘宝件对象集与同调充能唯一所有者(种行/补行改写时同步) | 构造注入;充能查询/消耗/按周期重置原语 | ConfigDB;TreasureItems 投放面;注入使用路径 |
| CurioStop | game/core/curio_stop.gd |
三选一停点编排唯一所有者(架构原则 9 本域承载):停点三态、刷新编排、兑付方法族、零自动推进语义 | 开停点/刷新/兑付/放行谓词/交断点片段五组入口+信号面(curio_choice_presented / curio_resolved) | ConfigDB;注入 CurioDeck、HeroStats、GainJournal、RefreshBank |
| breakpoint_store | game/core/breakpoint_store.gd |
存档断点组装与回放唯一承载:断点快照拼盘、回放回填、读侧策略分发 | BREAKPOINT_FIELDS 键登记单源(键名/策略标签/键序冻结) |
注入引用束 |
功能层
| 模块 | 文件 | 独占职责 | 对外封闭面 | 消费依赖 |
|---|---|---|---|---|
battle_orchestrator(B1,域文件集=编排器+settlement/ 五段段类+其拆件:BattleFxHost / RewardGrant / DamageController / BattleRefreshFlow / BoardInstaller / RoundCycle / BattleFacts / EffectPort / RewardRoller) |
game/core/battle_orchestrator.gd 等 |
战斗域编排唯一宿主:战斗状态机与生命周期、A2 三事件订阅、结算五段驱动(授予/增益减益/战斗/衰减/判定,段序冻结于 SettlementTable.segment_order)、行发射基建、呈现投影;战斗域全部跨系统调用权集中本域(静态扫描域 S7 执法,文件集清单单点=game/tests/static_scan.sh) |
begin_battle(encounter);窗口/刷新意图提交面;level_clear();步骤流(输出契约);明细行协议 |
B2/B3/B4 全调用面;A2 订阅;A1 generate;A3 代理+回发;D2 SettlementTable |
| level_runner(C1) | game/core/level_runner.gd |
关卡域生命周期:节点链推进、共享 B4、HP 携带、关卡末 level_clear;依赖构造注入一次给齐 | 节点推进接口;LevelTable(ConfigDB 跨表校验) | B1(直构接线战斗)、ConfigDB |
| run_structure(C2) | — | 冒险/关卡序列、失败重开、master_seed 唯一接线方 | (契约规范源:../../gdd/systems/冒险循环/冒险结构.md) |
RngService.set_master_seed、C3/D2 |
| difficulty(C3) | — | DifficultyTable 回填、全部曲线数值调参所有权、战斗期望表 | 调参输出(经 D2 解析传递,禁反向调用生成) | ConfigDB、B1 对账输出、A1 报告 |
| meta_progression(C4,业务层) | game/core/meta_progression.gd |
MetaTable、钥石账本、天赋树域、同调位槽位判定(业务规则与写口编排;数据原语归 MetaStateStore) | tree_* / forge_* / attune_* / settle_adventure / hero_override 族 | MetaStateStore、ConfigDB |
呈现层
| 模块 | 文件 | 独占职责 | 对外封闭面 | 消费依赖 |
|---|---|---|---|---|
| D1 HUD | game/presentation/main.gd(组合根)+三屏壳+views/ 视图单元族+ui_registry.gd |
全部 Control/CanvasLayer;输入→意图翻译(唯一提交路径=settle_batch,不直调 A3);组合根=信号接线与核心写调用唯一出口;views/ 各域呈现拆件的职责与接口归各件头注 | 组合根公开服务面与注册面句柄寻址合同(main.ui.<域容器>.<句柄>)归 main.gd / ui_registry.gd 头注承载 |
A2 compute_move_path;A3 只读;B1 步骤流;ConfigDB display_name;MEDIUM:Control/CanvasLayer/draw_*/InputEvent/RichTextLabel |
| 组合根拆件 | game/presentation/*_controller.gd / camp_shop_presenter.gd |
代组合根执行核心写调用(冒险节点推进/营地购买与刷新/道具使用) | 各拆件写入口(仅组合根装配面可达;视图零直连) | 构造注入的核心写引用 |
| HudPresenter | game/presentation/hud_presenter.gd |
战斗屏数据投影+文案拼装静态族(核心状态→呈现文案的全部翻译集中于此) | refresh 全量重查装配+只读静态投影族 | 只走 settlement.presentation_snapshot() 成文快照面(禁链式穿透) |
| board_resolvers | game/presentation/board_resolvers.gd |
棋盘每格渲染数据只读解析回调四函数(与无态静态投影族职责互斥) | 构造注入产出绑定 Callable 供组合根接线 | ConfigDB / 结算活态取值 Callable |
| battle_presentation(B5,垂直切片后) | — | 结算动画 / 伤害数字 / 战斗舞台 | (契约规范源:../../gdd/systems/战斗循环/战斗表现.md——前置「战斗表现美术测试」锁双舞台陷阱) |
B1 步骤流、D1;MEDIUM:AnimationPlayer/Tween |
| audio(D4,Alpha) | — | 音频挂点 | 挂点=B1 明细行类型流(负反馈聚合——单结算至多一次) | B1 流水 |
| tutorial(D5,Alpha) | — | 教学条目 | 口径来源=A2/A3/B3/B1 各教学条目 | 各上游 |
依赖单向性:上层可消费下层,禁止反向(C3 禁调用 A1 生成、D1 不直调 A3、A2/B3/B4 零相互直调)。全项目唯一回边=A2 事件订阅面。
呈现层装配与会话生命周期
三屏壳与组合根
- 呈现场景拆为三屏壳:MenuScreen(开始菜单屏)/CampScreen(营地屏)/AdventureScreen(冒险屏——内含关卡地图与战斗两容器)。
- 屏成员寻址经界面注册面(ui_registry):探针与消费方走
main.ui.<域容器>.<句柄>合同寻址;句柄清单与合同细节归 ui_registry 头注承载。 - 局态一律住 RunScope 节点,禁在屏/视图侧持有局态引用。
视觉层装配合同
- 树序=登记序=z 序,同源派生;层序唯一事实源=
main.gd的LAYER_CONTRACT常量表(kind 五类:shell/modal/state/node/float)。 - 全仓唯一落位口=
_apply_layer_contract()(装配尾统一排序+登记);散落move_child由冒烟源码断言判红;改层序只改合同表。 - 具体层清单不复制进本文(双写失同步禁令)——查现行层项直接读
main.gd。
会话生命周期(RunScope)
run_scope.gd=纯状态承载 Node:零信号连接、零视图构建、零核心写调用(连接只在组合根,组合根经run_scope.X读写)。- 会话更替机制:
_begin_session()新建会话节点挂树、旧会话节点整节点queue_free()——无独立收束函数,跨局字段清理靠节点释放机制。 - 存活性矩阵(九阶段 × 五引用面;执行判据=系统测试 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=按分支可空可活。对象有值但已失效一律判「悬挂」红。
模态编排(ModalFlow/ModalStack)
modal_flow.gd=模态编排纯逻辑类:开合编排(遮挡记账单口+演播后排窗挂起)/棋盘输入锁谓词/角标置灰谓词三职责;可直接new()单测。- 互斥排除语义随层登记(
register(node, tags));其余层零标签。
测试与质量域
定位:本节只写测试域的架构事实。测试工具手册与各闸判定口径的事实源=
game/tests/README.md;闸清单与改动域划分的唯一出处=tools/run_all_gates.sh(脚本即清单);测试怎么写、怎么算合格=design/engineering/test-conventions.md;静态扫描域 S 系规则的规则全集与动机=game/tests/README.md「Static Scan」节。全量验证=合回后远端 CI;开发期义务=改完即测(process-conventions §4)。
测试域依赖约束
测试域禁止反向依赖呈现层具体实现。五闸及其调用的探针场景、审计脚本只允许依赖两类边界:
- autoload 边界——ConfigDB / RngService 的公开面(--script 模式不加载 autoload 且不注册全局标识符,测试文件自带显式实例化夹具);
- 场景契约——探针场景的信号外发面与视图单元接口(信号外发、setter 只读注入),禁直引呈现层实现内部。
测试域是所有层的消费方,进入方式限于上述两类边界;除此之外的依赖方向一律与「模块归属」节依赖单向性同规。
数据流
1. 帧更新路径(2D 回合制:无逐帧玩法逻辑)
Input(鼠标)→ D1 输入翻译 → 意图对象 → A2.settle_batch(唯一提交入口)
→ A3.try_spend(原子扣减)→ A2 棋盘效果(挖/连锁/封印/移动)→ 三事件外发
→ [棋盘渲染:D1 BoardView 按事件增量重绘;无事件帧 = 静态 + 动效]
→ 轮次结束 → A3 Waiting → B1 结算编排(段序七段)→ 明细步骤流 → D1 结算屏逐行呈现
- 回合制下每帧只做:输入采样、呈现刷新、动效推进——玩法状态只在意图事务内变更(单意图帧输入收集:stop 点击终结当帧)。
- 无跨线程玩法数据流(Godot 主线程假设);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(唯一调用方)
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)。选型理由=可回放(架构原则 3):同步直连让调用顺序显式可见,「同种子逐位相同」才可断言;事件驱动形态服务的是并发/IO 场景对外部不确定时序的反应性,与本作「顺序确定」的需求相反。
- 事件规范序:A2 发射序=触发格 BFS、8 邻行主序;事件序契约
flag_judged<round_end全路径统一。 - 呈现层订阅禁令(切片缺陷教训固化):呈现层永不直接订阅排雷玩法/行动经济的事件流,只订战斗结算步骤流与
level_runner——核心事件形态变化不得直接冲击界面。
3. 存档/读档路径
- 存档系统已实装:格式、三槽位、断点域与迁移链的现行契约以
design/gdd/systems/表现与支撑/存档序列化.md(owner)为准。 - RNG 快照契约(约束,现行成立):断点续玩回填=master_seed + 各流 scope 计数器;快照切出须发生在无正在执行中的 open_stream 实例时(scope 事件边界外——切点=board install 边界);SAVE_FORMAT_VERSION 高版本拒读。
4. 打包与字体(CJK 随包发行)
CJK 字体随包发行并设为 theme 默认字体——运行时默认字体无中文字形。此项是 HUD 框架正式化的硬性前置,同时进导出 checklist 核对项。
5. 初始化顺序
进程启动
→ 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)
启动后置条件(执行判据事实源在 game/tests/system_test.gd):
- ConfigDB 就绪且表已载(
is_ready+ hero 表在座)。 - 系统设置已落引擎态——Master 音量 mute/volume_db=settings_store 现值;减动效开关=
UiKit.motion_scale。 - 启动态菜单可见(boot 后自树顶向下第一个可见内容层=开始层)。
- 续玩钮可见态恒等于断点在档态(双向)。
- 闲时会话已在树(
run_scope永非 null 契约的启动侧证明)。 - 调试浮窗 boot 不自动开(菜单优先)+调试入口全局浮层角标 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;先兑付后衰减;段内伤害序=主角先手→逐敌还手→地图账殿后) | 禁第二调用方(静态扫描域 S7: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 域增量已在 breaking-changes.md 登记,D1 采纳前对照核实。
架构原则
- 核心层纯逻辑、headless 完整可跑——核心层/功能层玩法逻辑零 Control/场景引用、零 UI 依赖;
--headless --script可跑完整战斗。输入是意图对象、输出是事件流/步骤流,D1 与输入设备皆可替换。 - 单一事实源与零字面量——玩法数值只存在于
data/tables/*.tres,经 ConfigDB 类型化单点读取;代码零玩法数值字面量;参数禁止跨系统复制(D2 Rule 1/2)。 - 封闭 RNG 与可回放——玩法代码零随机;一切随机经 RngService 具名封闭流(增流走 P1 评审);同种子 + 同输入序列 ⇒ 事件流/步骤流逐位相同(结算禁 await,B1 承重约束)。
- 编排唯一性与事件面封闭——战斗域跨系统调用权集中 B1(静态扫描承载);A2 三事件面封闭即负空间;每格受理、每雷转化、每次推进、每次衰减各恰一次。
- fail-fast + 零特判——数据错误一律致命中止(错误数值上线比崩溃更伤);API 非法=拒绝 + 诊断不静默;变异零运行时分支(行为差异全部由生成端约束保证)。
- 依赖单向 + 组合根模式——层间单向依赖、唯一回边=A2 事件订阅面;核心写调用唯一发生在组合根;禁上帝对象。
- 呈现层契约成文——面向呈现的信号载荷必须有成文 schema;模态覆盖层必须有"打开时遮挡物隐藏"场景级断言;场景级 UI 探针测试为标配(切片缺陷教训沉淀)。
- 系统无状态——效果引擎这类系统零运行时可变状态:数据由宿主对象持有并随宿主生灭,状态按参数传入系统,系统只做判定。系统实例不持计数器——计数器住桶(round/battle/level/adventure 四桶,EffectContext 引用束),桶住宿主。
- 停点权威在核心层——玩家决策停点(选路、三选一、商店、恢复这类)的推进守卫住核心层状态机:停点未兑付,推进口一律拒绝(零自动推进契约);呈现层模态只做开合与输入锁——阻塞是两层结构,核心守卫为权威、模态为体验;停点态是核心状态、随断点序列化,headless 跑批与真实局同一套规则,中断续玩恢复到同一停点。