两文件是流水线流程件而非游戏描述件,此前住在 design/gdd/ 造成三处不适配: gdd_lint 必须为它们逐条关掉体裁规则、格式权威却写在 doc-conventions §12、 与同族的 roadmap(在仓库根)分居两处。迁到根后按 roadmap.md 的无编号风格改名。 - 迁出:design/gdd/06-待办清单.md → 待办清单.md;07-体验验证清单.md → 体验验证清单.md - 指向改写 53 个文件:GDD 各系统文档指路存根、四份规约、02 根索引、README/roadmap/AGENTS - 两份清单自身 74 处出站链接按新基址重指(../art → design/art、systems → design/gdd/systems) - gdd_lint:待办/体验验证两文件的 R1/R3/R5/R7 豁免行随迁删除(已脱离扫描面),后门表清零 - pipeline_gate 默认路径、log_analysis/render_gate 称谓、repo_structure_audit 根文件白名单同步 - 保护面补写:两份清单列入实现批禁写清单(AGENTS 两类批条 / process-conventions §12 / 架构文档域表), 条目状态只由流水线各段推进 - 范围外未动(用户令「全不碰」):reports/ 与 design/research/ 的 22 处历史指向、game/ 两处注释
22 KiB
数据配置
一句话:数值表与单一事实源管线 状态:已定稿(自旧体系迁移)
设计目的
本系统是全部玩法数值的家。没有它,数字散落在代码里:调一次难度要翻改多处代码,战斗无法用固定种子复现,自动化测试也无从谈起。
它把两件事做成项目级纪律:其一,数字只写在数据表里、经统一读取口发放——改数值就是改表里的数,不动代码;其二,随机数只从封闭的具名通道发放——同种子必同局,这是全部回放与自动化测试的地基。它是玩家永远不该注意到的地基:不制造任何情绪,但失职会直接摧毁"可调、可测、可复现"这条信任底线。
系统范围
边界这样划:本系统管"数字放在哪、怎么装载校验、从哪读、随机从哪来"。各表的数值定成多少、玩法公式怎么算,归各回填责任方系统(回填:由归属系统把定稿数值填进表里,表结构先于数值存在);画成什么样归 HUD 框架,存档怎么存归存档序列化。本系统自身没有任何玩家可见行为。
负责:
| 负责 | 说明 |
|---|---|
| 全部数值表的结构与数据 | 表结构类(声明每列的类型、取值域与默认值)与数据文件成对交付;结构先行,数值由各回填责任方回填 |
| 全局读取口与随机服务 | 两个进程级单例:类型化读取口(代码标识符 ConfigDB)与统一随机流服务(代码标识符 RngService) |
| 加载、校验与热重载管线 | 启动加载、fail-fast 校验、调试构建热重载的状态管理 |
| 进度坐标查行 | 进度键表(跟着冒险进度成长的表)按(关卡序号 × 节点深度)两维坐标解析取行 |
| 表清单与对账 | 表路径固定、清单封闭;表实与 schema 声明逐字段对账 |
不负责:
| 不负责 | 归谁 |
|---|---|
| 各表数值定值与玩法公式 | 各回填责任方(清单见核心规则的表清单),平衡总归难度曲线与Boss |
| 存档格式与版本比较逻辑 | 存档序列化,本系统只出版本常量与随机快照契约 |
| 界面呈现 | HUD 框架 |
| 随机用途的设计合理性 | 消费方系统自证(随机须有界、可见或可推理),新增随机走扩签通道 |
在核心循环中的位置
进程启动:加载 + 校验全绿 ──▶ 全局读取口 / 随机服务 ──▶ 被全部玩法系统读取(循环路径之外)
本系统不在"扫雷—结算—推进"的循环路径上,是全员的地基:启动时把全部表校验装载就绪,之后每个系统从这里读自己的表、按事件取随机号。主种子在冒险开始时由冒险结构注入随机服务。
核心规则
单一事实源:数字只写在表里,取数只走一个口
单一事实源(本文含义:每个玩法数值只有一处权威载体,其余一律引用它)落到两条禁令上。第一,玩法代码零数值字面量:凡是设计师要调的数字,只存在于 data/tables/ 下的数据表里,代码里写死玩法数值即评审阻塞项。
第二,取数只走一个口:全部系统经全局读取口的类型化属性读数(读出来就是带类型的值,例如每轮行动点就是行动经济表里那个整数字段),禁止绕过它自己加载表文件或长期缓存副本——副本绕过校验,热重载换新值时它也不知情。
表结构与数据成对交付:结构定义先行(每个字段带类型、取值域与默认值),本系统先建齐全部占位表,具体数值由回填责任方按其系统文档回填——先有格子,后填数字。表结构零界面依赖:本系统代码不引用任何界面类,无窗口的命令行模式(headless)下也能跑完整战斗,自动化测试才有载体。
一句话总结这条规则:改数值 = 改表回填,不动代码;表不变,行为逐位相同。仅调试构建存在两个额外通道:从命令行注入的根目录加载测试夹具表;调试覆盖值可临时改读数、不回写表文件,正式构建结构性不存在覆盖源。
现行表集合如下(表结构类名供代码标识与工具链检索):
| 表 | 载什么 | 回填责任方 |
|---|---|---|
行动经济表 ActionEconomyTable |
每轮行动点、动作价目、停手与刷新门槛 | 行动经济 |
棋盘生成参数表 BoardGenTable |
板尺寸、雷密度、可推理率目标等(进度键表) | 棋盘生成 |
变异表 VariationTable |
变异类型清单(现行六行:region 六行两轴×三关〔2026-09-20 落地〕;首发 global 整图型贫矿脉 2026-10-16 用户令屏蔽删行,global 型机制代码保留) | 地形变异 |
敌人表 EnemyTable |
敌种基线数值、遭遇数量区间、护甲类型、技能池模板(进度键表) | 敌人系统 |
技能表 SkillTable |
技能行定义(类型/倍率/冷却/增益引用)与保底阈值 | 敌人系统 |
主角表 HeroTable |
主角生命上限、基础攻击与护甲等级(armor_class)等单行战斗数值 | 敌人系统 |
状态效果表 StatusEffectTable |
增益/减益效果定义行 | 增益状态 |
奖励表 RewardTable |
奖励条目、类别、权重与档位 | 地图战斗资源 |
结算表 SettlementTable |
结算段序、当量参考敞口、封顶与克制矩阵(单行全局) | 战斗结算 |
秘宝表 TreasureItemTable(treasure_items.tres) |
秘宝定义行 | 秘宝 |
难度表 DifficultyTable |
难度修饰乘数(占位空表) | 难度曲线与Boss |
关卡表 LevelTable |
逐关节点图与层名 | 冒险结构 |
冒险表 AdventureTable |
关卡大奖励与钥石入账(单行全局) | 冒险结构 |
元进度表 MetaTable |
元进度字段(已建表 2026-09-21——现行五行族:属性锻造 / Boss 钥石 / 工坊阈值 / 换算率 / 同调刷新升级行族,顺带扩列) | 元进度 |
举证:本节为数据纪律约定,无计算。违规检测 = 静态扫描加人工复核,随各表回填定稿与里程碑检查执行。
统一随机流:随机只从一个服务按号取,同种子必同局
全项目的随机数只经随机服务的统一流发放(2026-09-27 用户两轮复裁,七流并一并加全事件日志)。统一流(本文含义:唯一主种子 + 唯一派生公式〔单盐〕+ 唯一全局取数计数器)是对"随机即失控"的制度化设防:玩法代码禁止自建随机源、禁止调用全局随机函数。目的只有一个——同一条主种子(master_seed,一场冒险的随机源头数字,由冒险结构在冒险开始时注入,仅全局计数器归零时受理)驱动下,相同决策序列必然跑出相同结果,这是回放、审计与自动化测试共同的立足点。
取号按用途标签记账。用途标签(本文含义:取号时声明的用途名,只进事件日志、不参与种子派生)沿用并流前七条流名作封闭词表——标签让日志可读,也让"哪类事件在什么时机取号"仍保有登记位:
| 用途标签 | 消费方 | 用途:何时取号 |
|---|---|---|
| board_gen | 棋盘生成 | 每次生成新雷图(换图时)取号,布雷随机全部由该次取号实例供给 |
| reward_roll | 地图战斗资源 | 每次装板时的奖励预分配批(格子奖励批 + 清图奖励批)取号 |
| encounter | 战斗结算 | 每场战斗实例化取号,掷骰决定敌方实际数量 |
| armor_roll / behavior_roll / variant_place / gp_drop | 战斗结算 | 命中掷点逐次 / 开轮逐敌摇号 / 每板变异布置 / 每战末掉落掷定(结算表 armor_roll_stream 字段只作标签) |
取数有两个入口。玩法代码用取号入口:每调用一次,全局计数器加一并派生新种子,同一事件内共享同一实例。测试与预览用纯函数入口:按指定全局序号计算种子、不推计数器——预览不污染正式序列。种子由登记的派生公式计算(单盐),纯函数、跨引擎版本恒定,并登记了可复算的黄金向量。
全事件日志(并流批新增):冒险开始即开日志会话(user://logs/rng_log_<主种子>.jsonl),每次取数落一行——全局序号、用途标签、派生种子。号位在全序账本下不再单独回答"第 N 次某类事件"(路线依赖为已裁决代价),单点定位与复盘由日志承载。写盘失败只告警降级,不致命、不影响玩法随机。
生命周期:进程启动后流待命(未注入主种子就取数,致命中止,禁止默认种子兜底)→ 冒险开始注入主种子并开日志会话 → 冒险中按事件取号(全局计数器只增不重置)→ 冒险结束流保留供复盘。续玩与复盘的快照 = 主种子加全局取数计数器,由存档序列化消费;快照切出须发生在没有在用取号实例的时刻。要新增随机用途(含战斗内随机),走扩签通道:改代码加用途标签并通过评审——词表封闭是刻意的设卡。
举证:派生公式与实现规约见 game/core/rng_service.gd(盐与派生常量为代码事实),黄金向量断言见 game/smoke/smoke_all.gd;本文不转载。
fail-fast 校验:宁可启动失败,不带病运行
数据出错的处置只有一条铁律:致命中止,无软回退——错误数值上线比崩溃更伤信任底线。fail-fast(本文含义:校验不通过宁可立即中止,也不带着错误数据继续运行)按两个时机分开承载:加载期错误先收集后统一显示错误,一次看全所有错再中止;运行期错误当场致命,两者处置分开。
| 错误类别 | 什么情况 | 处置 |
|---|---|---|
| 加载期校验错误 | 字段越界、类型不符、表为空、缺入口锚行、重复键、权重和为零、悬空引用、段序违例 | 收集后统一显示错误,致命中止并输出错误清单 |
| 运行期致命 | 进度坐标越域请求、未设主种子就取随机数 | 不分构建走致命错误路径;无窗口模式进程非 0 退出 |
进程启动 ──▶ 逐表加载 ──▶ 逐表校验 ──┬─ 全部通过 ──▶ 就绪:类型化读数可读
└─ 任一错误 ──▶ 输出错误清单,致命中止
热重载(不重启进程、当场重新加载表文件的调试手段,仅调试构建)单独一套处置:战斗进行中的重载请求被闸门拒绝(闸门由战斗结算在战斗开始时置位、结束复位),重载校验失败时保留旧表继续运行并给出错误清单——不杀调试会话,这是全部规则里唯一的软着陆。调试构建之外,加载与校验在任何构建形态一律致命。随机服务的状态线独立于表加载:重载成败都不触碰主种子与计数器。
举证:本节为处置纪律约定,无计算。校验双通道(正式通道致命、测试通道收集供冒烟逐类断言)与夹具注入为实现参照,见 game/core/config_db.gd 实现。
悬空引用校验:跨表引用指到的键必须存在
一张表的字段引用另一张表的键时(例如奖励表某行声明自己授予某个增益效果,效果键必须真的在状态效果表里存在),加载期做存在性校验;指到不存在的键即悬空引用(本文含义:A 表填了 B 表的键,而 B 表里没有这个键),致命中止。这条校验防的是"改了 A 表忘了 B 表":删掉或改名一个键,所有指向它的引用当场暴露,而不是运行期才以莫名行为呈现。现行已激活的引用链有两条:奖励表的效果键与结算表的效果池映射键,都精确指向状态效果表。
举证:本节为校验纪律约定,无计算。逐表引用字段的登记见各回填责任方文档。
进度坐标查行:跟着冒险进度成长的表带两维坐标
跟着冒险进度成长的表(难度、生成参数、敌人配置)每行带(关卡序号 × 节点深度)两维坐标——难度曲线的雕刻轴从第一天就留在表结构层,而不是散落各处的魔法数字。解析规则两条:其一,进度坐标向上取整(2026-09-18 用户拍板修订,原「就近向下」退役)——无精确行时取不低于请求坐标的最近已有行并留一条警告(警告按"哪张表、缺哪维、停在哪个键"去重,是开发期异常信号而非审计工具);取整方向的理由是保证偏难:宁可在内容缺口上高估难度让工具读数保守,不可静默降难掩盖断档;请求坐标低于合法域(关卡序号 <1、节点深度 <0)不属于取整,走运行期致命;请求高于最大已有行时取最大已有行封顶(2026-09-18 追加拍板:可取范围内向上取整,超出最大值就用最大值,封顶同样留警告)。其二,实体键精确匹配,那一行没有这个名字就是悬空引用,直接致命中止——进度可以向上近似,"是哪种敌人"不能近似,身份近似会静默改变遭遇构成。
三条配套边界。每关必须含深度 0 的锚行(关卡入口行),缺失即加载期致命,防止入口请求静默落到深处行造成难度突刺。请求越域(关卡序号小于 1 或深度为负)在进入解析前致命中止。没有兜底行、没有外推:超过表范围的成长外推归难度曲线与Boss的公式职责,本系统只解析到最近已有行——解析永不发明数据。
表键本身不是永久契约:当现有键定不了新的内容形态(例如某种节点形态无法由现有键唯一确定),走本文的改键修订通道,与各表 schema 同批改。
举证:解析为查表逻辑,无计算;难度审计由离线的曲线导出工具承担(见 P1 / P2 后置)。
分工:表载活值,owner 文档定规则与归属
各系统的 owner 文档登记"哪个实体归哪个系统所有、哪些字段与值已锁定",数据表载的是活值——调参就改表。两处不一致时,任何一边都不允许默默改值:冲突必须显式提出,修订走回填责任方的文档修订批,术语涉及时同批改术语表。
对账口径:每张表定稿回填时,表结构与已锁字段须与其 schema 声明逐字段一致,各系统文档的验收标准都含这条"表实一致";对不上就是缺陷,不是可容忍的漂移。本系统对玩法数值表只读:表值只能由归属系统(回填责任方)的修订批改动。
举证:本节为对账约定,无计算。
依赖与输出
本系统是地基层:对上游无依赖,对下游是全项目的读数面与随机面。这张表就是删除任何一方时的影响面清单。
| 方向 | 对象 | 接口要点 |
|---|---|---|
| 上游 | 无 | 地基层,不依赖任何玩法系统 |
| 下游 | 全部玩法系统 | 唯一取数路径:全局读取口的类型化属性读取(排雷玩法等无独立接口面的系统经本行消费) |
| 下游 | 棋盘生成 | 生成参数表承载与加载校验;board_gen 流取号 |
| 下游 | 行动经济 | 行动经济表承载 |
| 下游 | 地形变异 | 变异表承载(空清单合法态) |
| 下游 | 敌人系统 | 敌人表与主角表承载 |
| 下游 | 增益状态 | 状态效果表承载;悬空引用校验的被指方 |
| 下游 | 地图战斗资源 | 奖励表与奖励配置表承载;reward_roll 流取号 |
| 下游 | 战斗结算 | 结算表承载;热重载闸门置位与复位;encounter 流取号 |
| 下游 | 秘宝 | 秘宝表承载 |
| 下游 | 冒险结构 | 关卡表与冒险表承载(登记现状见「待办」);主种子注入入口 |
| 下游 | 难度曲线与Boss | 难度表承载(占位);进度坐标查行的消费方 |
| 下游 | 元进度 | 元进度表占位承载 |
| 下游 | 存档序列化 | 表结构版本常量;随机快照契约(主种子 + 全局取数计数器) |
| 下游 | HUD 框架 | 调试热重载完成通知(仅调试构建) |
| 外发 | 无订阅 | 本系统不订阅任何玩法事件 |
P0 最小闭环
- 结构先行:交付全部表结构类与占位表(含键结构),先有格子。
- 各回填责任方按系统定稿顺序回填数值。
- 进程启动:逐表加载、逐表校验,错误收集后统一显示错误;全绿进入就绪态。
- 全部系统经全局读取口读数,无第二取数路径。
- 冒险开始注入主种子并开事件日志会话,统一流按事件取号。
- 调试构建热重载即改即验:战斗中被闸门拒绝,结束后手动再触发。
- 无窗口冒烟脚本跑通加载、校验、取数、派生全链路,退出码 0。
P1 / P2 后置
| 优先级 | 内容 | 后置原因 |
|---|---|---|
| P1 | 战斗级可回放集成测试(同主种子同动作序列,步骤流逐行相同) | 需战斗域载体,随战斗结算回放验收兑现 |
| P1 | 难度曲线导出工具(无窗口导出行解析矩阵供比对) | 难度审计的离线载体,难度曲线与Boss期交付物 |
| P2 | 正式包构建的致命表现验证与调试覆盖结构性不存在验证 | 挂首次正式导出检查清单 |
| P2 | 进度键表的调试覆盖行寻址语法 | 调试覆盖现只支持单行全局表字段,行寻址登记为后续扩展 |
| P2 | 编辑器内表文件热重载自动化 | 低优先,未指派 |
调参表
本文是表的管理者,不是数值的 owner:各表的玩法参数与现行值见各回填责任方文档的调参表,已锁数值以各表 .tres 为准。本系统自有的是管线常量——它们决定管线怎么运转,绝大多数冻结、非调参项:
| 参数 | 现行值 | 说明 |
|---|---|---|
| 表路径清单 | data/tables/ 固定(调试注入根除外) | 冻结:散装路径破坏单点访问 |
表结构版本常量 SCHEMA_VERSION |
当前 = 2(v2=断点域出生,迭代 8 卡①,与存档 SAVE_FORMAT_VERSION 同源) | 全部表结构携带版本字段;高于当前支持的版本拒读,比较逻辑归存档序列化 |
| 随机流口径 | 统一流单盐单计数器 + 七用途标签封闭词表 | 统一口径为 2026-09-27 裁决;扩签 = 改代码 + 评审,有意设卡 |
| 进度坐标解析策略 | 可取范围内向上取整 + 警告(保证偏难);超出最大行封顶取最大值 + 警告;域越界致命(2026-09-18 两段拍板,原「就近向下」退役) | 冻结:静默降难会掩盖难度断档 |
| 入口锚行校验 | 写死开 | 非调参项;重议走文档修订流程 |
| 调试覆盖开关 | 仅调试构建,默认关 | 正式构建结构性不存在;覆盖值永不回写表文件 |
验收标准
- 干净检出:无窗口冒烟脚本从干净检出启动,表清单内全部表加载成功且表目录无清单外文件;任一失败输出错误清单并退出非 0。
- 校验类别全覆盖:越界、文件缺失、空表、缺锚行、重复键、权重和为零、悬空引用各有一份测试夹具,逐类断言错误类别。
- 致命真的会死:任一致命夹具经正式通道加载,进程非 0 退出,而非仅"校验器能发现"。
- 黄金向量:随机派生纯函数对登记向量逐个复算相等;同输入恒同输出;同序号重复调用恒等。
- 计数器纪律:连续取号跨模拟关卡切换,计数器单调不重置;热重载成败都不改变主种子与计数器。
- 向上取整解析:请求无精确行时返回不低于请求坐标的最近行并留一条警告;请求超出最大已有行时封顶取最大行并留警告;同类警告去重;精确命中零警告。
- 越域与未播种:坐标低于合法域(关卡序号 <1、节点深度 <0)在进入解析前致命中止(Fatal 级诊断 + 进程退出码 1,致命类单测
tests/unit/data_config/config_db_fatal_oob_test.gd验证——迭代 19 卡① T4 探针退役顺带改指,原切片探针断言面与 run_all 致命类单测重复故退役);高于最大已有行走封顶取最大行(警告留痕,不致命);未设主种子就取随机数致命中止,无默认种子兜底。 - 热重载门:战斗中重载被拒绝且读数不变、不发通知;门未置位时新值可读且通知恰一次;校验失败保留旧表停留就绪态。
- 版本常量在位:表结构版本常量存在且全部表结构携带版本字段(高版本拒读判定归存档序列化)。
- 零字面量、零第二路径:静态扫描加人工复核确认玩法代码无数值字面量、无读取口之外的表加载、无全局随机函数调用。
- 零界面依赖:本系统代码不引用任何界面类,无窗口实跑通过(静态扫描与实跑两项合成判定)。
- 表实一致:各表结构与已锁字段和
data/schemas/对应声明逐字段一致。
待办
本系统待办条目已统一收编至 待办清单,本节不再逐条登记。