Files
gplan-2/design/gdd/systems/表现与支撑/数据配置.md
T

21 KiB
Raw Blame History

数据配置

一句话:数值表与单一事实源管线 状态:已定稿;现行为 v1.3

设计目的

本系统是全部玩法数值的家。没有它,数字散落在代码里:调一次难度要翻改多处代码,战斗无法用固定种子复现,自动化测试也无从谈起。

它把两件事做成项目级纪律:其一,数字只写在数据表里、经统一读取口发放——改数值就是改表里的数,不动代码;其二,随机数只从封闭的具名通道发放——同种子必同局,这是全部回放与自动化测试的地基。它是玩家永远不该注意到的地基:不制造任何情绪,但失职会直接摧毁"可调、可测、可复现"这条信任底线。

系统范围

边界这样划:本系统管"数字放在哪、怎么装载校验、从哪读、随机从哪来"。各表的数值定成多少、玩法公式怎么算,归各回填责任方系统(回填:由归属系统把定稿数值填进表里,表结构先于数值存在);画成什么样归 HUD 框架,存档怎么存归存档序列化。本系统自身没有任何玩家可见行为。

负责:

负责 说明
全部数值表的结构与数据 表结构类(声明每列的类型、取值域与默认值)与数据文件成对交付;结构先行,数值由各回填责任方回填
全局读取口与随机服务 两个进程级单例:类型化读取口与统一随机流服务
加载、校验与热重载管线 启动加载、fail-fast 校验、调试构建热重载的状态管理
进度坐标查行 进度键表(跟着冒险进度成长的表)按(关卡序号 × 节点深度)两维坐标解析取行
表清单与对账 表路径固定、清单封闭;表实与 schema 声明逐字段对账

不负责:

不负责 归谁
各表数值定值与玩法公式 各回填责任方(清单见核心规则的表清单),平衡总归难度曲线与Boss
存档格式与版本比较逻辑 存档序列化,本系统只出随机快照契约
界面呈现 HUD 框架
随机用途的设计合理性 消费方系统自证(随机须有界、可见或可推理),新增随机走扩签通道

在核心循环中的位置

进程启动:加载 + 校验全绿 ──▶ 全局读取口 / 随机服务 ──▶ 被全部玩法系统读取(循环路径之外)

本系统不在"扫雷—结算—推进"的循环路径上,是全员的地基:启动时把全部表校验装载就绪,之后每个系统从这里读自己的表、按事件取随机号。主种子在冒险开始时由冒险结构注入随机服务。

核心规则

单一事实源:数字只写在表里,取数只走一个口

单一事实源(本文含义:每个玩法数值只有一处权威载体,其余一律引用它)落到两条禁令上。第一,玩法代码零数值字面量:凡是设计师要调的数字,只存在于 data/tables/ 下的数据表里,代码里写死玩法数值即评审阻塞项。

第二,取数只走一个口:全部系统经全局读取口的类型化属性读数(读出来就是带类型的值,例如每轮行动点就是行动经济表里那个整数字段),禁止绕过它自己加载表文件或长期缓存副本——副本绕过校验,热重载换新值时它也不知情。

表结构与数据成对交付:结构定义先行(每个字段带类型、取值域与默认值),本系统先建齐全部占位表,具体数值由回填责任方按其系统文档回填——先有格子,后填数字。表结构零界面依赖:本系统代码不引用任何界面类,无窗口的命令行模式(headless)下也能跑完整战斗,自动化测试才有载体。

一句话总结这条规则:改数值 = 改表回填,不动代码;表不变,行为逐位相同。仅调试构建存在两个额外通道:从命令行注入的根目录加载测试夹具表;调试覆盖值可临时改读数、不回写表文件,正式构建结构性不存在覆盖源。

现行表集合如下:

表 载什么 回填责任方
行动经济表 每轮行动点、动作价目、停手与刷新门槛 行动经济
棋盘生成参数表 板尺寸、雷密度、可推理率目标等(进度键表) 棋盘生成
变异表 变异类型清单(现行六行:region 六行两轴×三关;global 整图型贫矿脉行已删,global 型机制代码保留) 地形变异
敌人表 敌种基线数值、遭遇数量区间、护甲类型、技能池模板(进度键表) 敌人系统
技能表 技能行定义(类型/倍率/冷却/增益引用/触发条件)与保底阈值 敌人系统
主角表 主角生命上限、基础攻击与护甲等级(armor_class)等单行战斗数值 敌人系统
状态效果表 增益/减益效果定义行 增益状态
奖励表 奖励条目、类别、权重与档位 地图战斗资源
结算表 结算段序、当量参考敞口、封顶与克制矩阵(单行全局) 战斗结算
秘宝表(treasure_items.tres) 秘宝定义行 秘宝
难度表 难度修饰乘数(占位空表) 难度曲线与Boss
关卡表 逐关节点图与层名 冒险结构
冒险表 关卡大奖励与钥石入账(单行全局) 冒险结构
元进度表 元进度字段(现行五行族:属性锻造 / Boss 钥石 / 工坊阈值 / 换算率 / 同调刷新升级行族) 元进度
战斗屏布局表(battle_layout.tres) 分区几何、B 区连续地面层高与明细带两态高(单行;呈现层布局配置,非玩法数值——供呈现层与样张工具同源读取) 战斗屏规格(结构)/HUD框架(呈现常量)

举证:本节为数据纪律约定,无计算。违规检测 = 静态扫描加人工复核,随各表回填定稿与里程碑检查执行。

统一随机流:随机只从一个服务按号取,同种子必同局

全项目的随机数只经随机服务的统一流发放(2026-09-27 用户两轮复裁,七流并一并加全事件日志)。统一流(本文含义:唯一主种子 + 唯一派生公式〔单盐〕+ 唯一全局取数计数器)是对"随机即失控"的制度化设防:玩法代码禁止自建随机源、禁止调用全局随机函数。目的只有一个——同一条主种子(master_seed,一场冒险的随机源头数字,由冒险结构在冒险开始时注入,仅全局计数器归零时受理)驱动下,相同决策序列必然跑出相同结果,这是回放、审计与自动化测试共同的立足点。

取号按用途标签记账。用途标签(本文含义:取号时声明的用途名,只进事件日志、不参与种子派生)沿用七条流名作封闭词表——标签让日志可读,也让"哪类事件在什么时机取号"仍保有登记位:

用途标签 消费方 用途:何时取号
board_gen 棋盘生成 每次生成新雷图(换图时)取号,布雷随机全部由该次取号实例供给
reward_roll 地图战斗资源 每次装板时的奖励预分配批(格子奖励批 + 清图奖励批)取号
encounter 战斗结算 每场战斗实例化取号,掷骰决定敌方实际数量
armor_roll / behavior_roll / variant_place / gp_drop 战斗结算 命中掷点逐次 / 开轮逐敌摇号 / 每板变异布置 / 每战末掉落掷定(结算表 armor_roll_stream 字段只作标签)

取数有两个入口。玩法代码用取号入口:每调用一次,全局计数器加一并派生新种子,同一事件内共享同一实例。测试与预览用纯函数入口:按指定全局序号计算种子、不推计数器——预览不污染正式序列。种子由登记的派生公式计算(单盐),纯函数、跨引擎版本恒定,并登记了可复算的黄金向量。

全事件日志:冒险开始即开日志会话(随机事件日志文件,每主种子一份),每次取数落一行——全局序号、用途标签、派生种子。号位在全序账本下不再单独回答"第 N 次某类事件"(路线依赖为已裁决代价),单点定位与复盘由日志承载。写盘失败只告警降级,不致命、不影响玩法随机。

生命周期:进程启动后流待命(未注入主种子就取数,致命中止,禁止默认种子兜底)→ 冒险开始注入主种子并开日志会话 → 冒险中按事件取号(全局计数器只增不重置)→ 冒险结束流保留供复盘。续玩与复盘的快照 = 主种子加全局取数计数器,由存档序列化消费;快照切出须发生在没有在用取号实例的时刻。要新增随机用途(含战斗内随机),走扩签通道:改代码加用途标签并通过评审——词表封闭是刻意的设卡。

举证:派生公式(单盐)由随机服务持有,本文不转载;黄金向量已登记可复算,逐向量复算相等即验收判据。

fail-fast 校验:宁可启动失败,不带病运行

数据出错的处置只有一条铁律:致命中止,无软回退——错误数值上线比崩溃更伤信任底线。fail-fast(本文含义:校验不通过宁可立即中止,也不带着错误数据继续运行)按两个时机分开承载:加载期错误先收集后统一显示错误,一次看全所有错再中止;运行期错误当场致命,两者处置分开。

错误类别 什么情况 处置
加载期校验错误 字段越界、类型不符、表为空、缺入口锚行、重复键、权重和为零、悬空引用、段序违例 收集后统一显示错误,致命中止并输出错误清单
运行期致命 进度坐标越域请求、未设主种子就取随机数 不分构建走致命错误路径;无窗口模式进程非 0 退出
进程启动 ──▶ 逐表加载 ──▶ 逐表校验 ──┬─ 全部通过 ──▶ 就绪:类型化读数可读
                                     └─ 任一错误 ──▶ 输出错误清单,致命中止

热重载(不重启进程、当场重新加载表文件的调试手段,仅调试构建)单独一套处置:战斗进行中的重载请求被闸门拒绝(闸门由战斗结算在战斗开始时置位、结束复位),重载校验失败时保留旧表继续运行并给出错误清单——不杀调试会话,这是全部规则里唯一的软着陆。调试构建之外,加载与校验在任何构建形态一律致命。随机服务的状态线独立于表加载:重载成败都不触碰主种子与计数器。

举证:本节为处置纪律约定,无计算。校验双通道与夹具注入为实现参照,本文不转载。

悬空引用校验:跨表引用指到的键必须存在

一张表的字段引用另一张表的键时(例如奖励表某行声明自己授予某个增益效果,效果键必须真的在状态效果表里存在),加载期做存在性校验;指到不存在的键即悬空引用(本文含义: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 最小闭环

  1. 结构先行:交付全部表结构类与占位表(含键结构),先有格子。
  2. 各回填责任方按系统定稿顺序回填数值。
  3. 进程启动:逐表加载、逐表校验,错误收集后统一显示错误;全绿进入就绪态。
  4. 全部系统经全局读取口读数,无第二取数路径。
  5. 冒险开始注入主种子并开事件日志会话,统一流按事件取号。
  6. 调试构建热重载即改即验:战斗中被闸门拒绝,结束后手动再触发。
  7. 无窗口冒烟脚本跑通加载、校验、取数、派生全链路,退出码 0。

P1 / P2 后置

优先级 内容 后置原因
P1 战斗级可回放集成测试(同主种子同动作序列,步骤流逐行相同) 需战斗域载体,随战斗结算回放验收兑现
P1 难度曲线导出工具(无窗口导出行解析矩阵供比对) 难度审计的离线载体,难度曲线与Boss期交付物
P2 正式包构建的致命表现验证与调试覆盖结构性不存在验证 挂首次正式导出检查清单
P2 进度键表的调试覆盖行寻址语法 调试覆盖现只支持单行全局表字段,行寻址登记为后续扩展
P2 编辑器内表文件热重载自动化 低优先,未指派

调参表

本文是表的管理者,不是数值的 owner:各表的玩法参数与现行值见各回填责任方文档的调参表,已锁数值以各表 .tres 为准。本系统自有的是管线常量——它们决定管线怎么运转,绝大多数冻结、非调参项:

参数 现行值 说明
表路径清单 data/tables/ 固定(调试注入根除外) 冻结:散装路径破坏单点访问
随机流口径 统一流单盐单计数器 + 七用途标签封闭词表 统一口径为 2026-09-27 裁决;扩签 = 改代码 + 评审,有意设卡
进度坐标解析策略 可取范围内向上取整 + 警告(保证偏难);超出最大行封顶取最大值 + 警告;域越界致命(2026-09-18 两段拍板) 冻结:静默降难会掩盖难度断档
入口锚行校验 写死开 非调参项;重议走文档修订流程
调试覆盖开关 仅调试构建,默认关 正式构建结构性不存在;覆盖值永不回写表文件

验收标准

  • 干净检出:无窗口冒烟脚本从干净检出启动,表清单内全部表加载成功且表目录无清单外文件;任一失败输出错误清单并退出非 0。
  • 校验类别全覆盖:越界、文件缺失、空表、缺锚行、重复键、权重和为零、悬空引用各有一份测试夹具,逐类断言错误类别。
  • 致命真的会死:任一致命夹具经正式通道加载,进程非 0 退出,而非仅"校验器能发现"。
  • 黄金向量:随机派生纯函数对登记向量逐个复算相等;同输入恒同输出;同序号重复调用恒等。
  • 计数器纪律:连续取号跨模拟关卡切换,计数器单调不重置;热重载成败都不改变主种子与计数器。
  • 向上取整解析:请求无精确行时返回不低于请求坐标的最近行并留一条警告;请求超出最大已有行时封顶取最大行并留警告;同类警告去重;精确命中零警告。
  • 越域与未播种:坐标低于合法域(关卡序号 <1、节点深度 <0)在进入解析前致命中止(Fatal 级诊断 + 进程非 0 退出,无兜底);高于最大已有行走封顶取最大行(警告留痕,不致命);未设主种子就取随机数致命中止,无默认种子兜底。
  • 热重载门:战斗中重载被拒绝且读数不变、不发通知;门未置位时新值可读且通知恰一次;校验失败保留旧表停留就绪态。
  • 零字面量、零第二路径:静态扫描加人工复核确认玩法代码无数值字面量、无读取口之外的表加载、无全局随机函数调用。
  • 零界面依赖:本系统代码不引用任何界面类,无窗口实跑通过(静态扫描与实跑两项合成判定)。
  • 表实一致:各表结构与已锁字段和表结构声明逐字段一致。

待办

本系统待办条目已统一收编至 待办清单,本节不再逐条登记。