feat: 收敛玩法运行时配置并加入故障恢复
This commit is contained in:
239
doc/gameplay/故障恢复机制.md
Normal file
239
doc/gameplay/故障恢复机制.md
Normal file
@@ -0,0 +1,239 @@
|
||||
# 故障恢复机制
|
||||
|
||||
本文档用于说明当前客户端在“游戏进行中非正常退出”场景下的恢复机制。
|
||||
|
||||
目标:
|
||||
|
||||
- 明确当前恢复能力边界
|
||||
- 说明恢复快照保存什么、不保存什么
|
||||
- 说明恢复流程、清理流程和测试方法
|
||||
|
||||
---
|
||||
|
||||
## 1. 设计原则
|
||||
|
||||
当前恢复机制采用:
|
||||
|
||||
`轻量快照恢复,而不是页面状态回放`
|
||||
|
||||
原则如下:
|
||||
|
||||
- 只恢复核心运行态
|
||||
- 不恢复瞬时 UI
|
||||
- 恢复后由规则层和展示层重新计算派生状态
|
||||
- 恢复失败时允许直接降级回正常开局
|
||||
- 不为了恢复体验牺牲主流程性能
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前恢复范围
|
||||
|
||||
### 2.1 会恢复的内容
|
||||
|
||||
- 当前配置入口
|
||||
- 当前对局核心状态
|
||||
- 已完成点 / 已跳过点
|
||||
- 当前分数
|
||||
- 开赛时间 / 结束时间 / 结束原因
|
||||
- 模式状态 `modeState`
|
||||
- 遥测累计值
|
||||
- 最后 GPS 点与精度
|
||||
- 地图基础视口
|
||||
- GPS 锁定状态
|
||||
|
||||
### 2.2 不恢复的内容
|
||||
|
||||
- 白色内容卡
|
||||
- 答题卡中间态
|
||||
- 黑底引导提示条
|
||||
- 彩色短反馈条
|
||||
- 待查看内容入口
|
||||
- 临时动画和过渡效果
|
||||
- 各类计时器、定时器、提示队列
|
||||
|
||||
说明:
|
||||
|
||||
这些内容都属于派生 UI 或瞬时体验,恢复后会重新按当前运行态计算,不直接持久化。
|
||||
|
||||
---
|
||||
|
||||
## 3. 快照结构
|
||||
|
||||
当前恢复快照定义在:
|
||||
|
||||
- [sessionRecovery.ts](D:/dev/cmr-mini/miniprogram/game/core/sessionRecovery.ts)
|
||||
|
||||
结构分为 4 块:
|
||||
|
||||
1. 快照元信息
|
||||
- `schemaVersion`
|
||||
- `savedAt`
|
||||
|
||||
2. 配置身份
|
||||
- `launchEnvelope`
|
||||
- `configAppId`
|
||||
- `configVersion`
|
||||
|
||||
3. 对局核心状态
|
||||
- `gameState`
|
||||
|
||||
4. 运行态附属状态
|
||||
- `telemetry`
|
||||
- `viewport`
|
||||
- `currentGpsPoint`
|
||||
- `currentGpsAccuracyMeters`
|
||||
- `currentGpsInsideMap`
|
||||
- `bonusScore`
|
||||
- `quizCorrectCount`
|
||||
- `quizWrongCount`
|
||||
- `quizTimeoutCount`
|
||||
|
||||
---
|
||||
|
||||
## 4. 保存时机
|
||||
|
||||
当前 V1 保存时机如下:
|
||||
|
||||
- 对局进入 `running` 时先保存一次
|
||||
- 对局进行中按低频节流定时保存
|
||||
- 页面 `onHide` 时保存一次
|
||||
- 页面 `onUnload` 时保存一次
|
||||
|
||||
当前默认节流周期:
|
||||
|
||||
- `5` 秒
|
||||
|
||||
说明:
|
||||
|
||||
- 不做每帧保存
|
||||
- 不在所有 GPS 更新时保存
|
||||
- 只做低频检查点式持久化
|
||||
|
||||
---
|
||||
|
||||
## 5. 恢复流程
|
||||
|
||||
当前恢复流程如下:
|
||||
|
||||
1. 页面进入时先解析启动入口
|
||||
2. 如果没有显式新启动参数,则检查是否存在恢复快照
|
||||
3. 若存在恢复快照,则优先使用快照中的 `launchEnvelope`
|
||||
4. 配置加载完成后校验快照身份
|
||||
5. 若快照属于当前配置,则弹出“继续恢复 / 放弃”确认
|
||||
6. 用户确认恢复后:
|
||||
- 先恢复系统设置运行态
|
||||
- 再恢复 `GameRuntime` 核心状态
|
||||
- 再恢复 `TelemetryRuntime`
|
||||
- 再恢复地图视口与 GPS 锁定态
|
||||
- 最后重新计算 HUD、按钮和提示
|
||||
|
||||
恢复相关落点:
|
||||
|
||||
- [map.ts](D:/dev/cmr-mini/miniprogram/pages/map/map.ts)
|
||||
- [mapEngine.ts](D:/dev/cmr-mini/miniprogram/engine/map/mapEngine.ts)
|
||||
- [gameRuntime.ts](D:/dev/cmr-mini/miniprogram/game/core/gameRuntime.ts)
|
||||
- [telemetryRuntime.ts](D:/dev/cmr-mini/miniprogram/game/telemetry/telemetryRuntime.ts)
|
||||
|
||||
---
|
||||
|
||||
## 6. 清理规则
|
||||
|
||||
以下情况会清除恢复快照:
|
||||
|
||||
- 正常完赛
|
||||
- 超时结束
|
||||
- 主动退出
|
||||
- 用户在恢复确认框中选择“放弃”
|
||||
- 快照配置身份与当前配置不匹配
|
||||
- 恢复失败
|
||||
|
||||
说明:
|
||||
|
||||
恢复快照只服务“未正常结束的进行中对局”。
|
||||
|
||||
---
|
||||
|
||||
## 7. 当前实现边界
|
||||
|
||||
当前 V1 的明确边界是:
|
||||
|
||||
- 支持续局
|
||||
- 不支持恢复答题进行中
|
||||
- 不支持恢复内容卡浏览进行中
|
||||
- 不支持恢复弹层堆栈
|
||||
- 不支持恢复临时 FX 状态
|
||||
|
||||
这不是缺陷,而是当前版本的刻意收敛。
|
||||
|
||||
---
|
||||
|
||||
## 8. 性能策略
|
||||
|
||||
当前恢复机制的性能策略如下:
|
||||
|
||||
- 快照只存小而必要的结构
|
||||
- 不重复存整份远端配置 JSON
|
||||
- 不存派生展示状态
|
||||
- 不做高频写入
|
||||
- 恢复后尽量走现有规则重算链
|
||||
|
||||
所以这套恢复机制更接近:
|
||||
|
||||
`保存运行核心状态 + 重新生成界面`
|
||||
|
||||
而不是:
|
||||
|
||||
`保存整个页面现场`
|
||||
|
||||
---
|
||||
|
||||
## 9. 测试建议
|
||||
|
||||
### 9.1 基础恢复
|
||||
|
||||
1. 开一局并至少完成 1 个点
|
||||
2. 不正常结束,直接退后台并杀掉程序
|
||||
3. 再次进入地图页
|
||||
4. 确认出现恢复提示
|
||||
5. 点击“继续恢复”
|
||||
6. 确认分数、已完成点、计时和地图状态都能续上
|
||||
|
||||
### 9.2 放弃恢复
|
||||
|
||||
1. 重复上面步骤进入恢复提示
|
||||
2. 点击“放弃”
|
||||
3. 确认回到正常初始状态
|
||||
4. 再次进入时不应重复提示
|
||||
|
||||
### 9.3 正常结束清理
|
||||
|
||||
分别验证:
|
||||
|
||||
- 正常打终点结束
|
||||
- 主动退出
|
||||
- 超时结束
|
||||
|
||||
结果都应为:
|
||||
|
||||
- 不再保留恢复快照
|
||||
- 再次进入不再提示恢复
|
||||
|
||||
---
|
||||
|
||||
## 10. 后续演进方向
|
||||
|
||||
后续如果要继续增强,建议顺序如下:
|
||||
|
||||
1. 先补恢复链的 smoke tests
|
||||
2. 再考虑恢复更多遥测累计细节
|
||||
3. 最后才考虑是否恢复答题态或内容态
|
||||
|
||||
不建议一开始就追求全量 UI 恢复。
|
||||
|
||||
---
|
||||
|
||||
## 11. 一句话结论
|
||||
|
||||
当前故障恢复机制的定位是:
|
||||
|
||||
**保证玩家在异常退出后可以继续当前对局,但不承担恢复所有临时界面状态。**
|
||||
380
doc/gameplay/游戏规则架构.md
Normal file
380
doc/gameplay/游戏规则架构.md
Normal file
@@ -0,0 +1,380 @@
|
||||
# 游戏规则架构
|
||||
|
||||
本文档用于说明当前项目中“游戏规则”在文档、配置文件、样例 JSON、解析代码和运行时规则引擎之间的实际组织方式。
|
||||
|
||||
目标:
|
||||
|
||||
- 说明规则设计从哪里开始
|
||||
- 说明公共配置和玩法配置如何分层
|
||||
- 说明样例配置、代码解析、运行时规则如何对应
|
||||
- 作为后续后台配置管理的架构基线
|
||||
|
||||
---
|
||||
|
||||
## 1. 总体原则
|
||||
|
||||
当前项目采用的是“文档定义规则,配置承载规则,代码解析配置,规则引擎执行配置”的结构。
|
||||
|
||||
可以概括为四句话:
|
||||
|
||||
1. 玩法规则先在文档里定义
|
||||
2. 规则通过 JSON 配置文件表达
|
||||
3. 客户端解析配置生成运行态定义
|
||||
4. 规则引擎按运行态定义驱动游戏流程
|
||||
|
||||
也就是说:
|
||||
|
||||
**文档是设计源头,配置是规则载体,代码是执行层。**
|
||||
|
||||
如果换一种更偏运行时的说法:
|
||||
|
||||
- `MapEngine` 和页面壳子是骨架
|
||||
- 默认值层和规则层决定骨架怎么动
|
||||
- 配置像神经系统,把活动差异传进运行时
|
||||
- 遥测和反馈层负责把玩家状态再回流到界面
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前分层结构
|
||||
|
||||
当前规则体系分成 6 层。
|
||||
|
||||
### 2.1 公共规则层
|
||||
|
||||
位置:
|
||||
|
||||
- [全局规则与配置维度清单](D:/dev/cmr-mini/doc/config/全局规则与配置维度清单.md)
|
||||
- [配置选项字典](D:/dev/cmr-mini/doc/config/配置选项字典.md)
|
||||
- [当前最全配置模板](D:/dev/cmr-mini/doc/config/当前最全配置模板.md)
|
||||
|
||||
作用:
|
||||
|
||||
- 定义系统共用能力有哪些
|
||||
- 定义公共字段、可选项和默认值
|
||||
- 作为所有玩法的公共配置全集
|
||||
|
||||
这一层回答的是:
|
||||
|
||||
- 系统支持哪些规则块
|
||||
- 系统有哪些字段
|
||||
- 这些字段默认怎么工作
|
||||
|
||||
### 2.2 玩法设计层
|
||||
|
||||
位置:
|
||||
|
||||
- [程序默认规则基线](D:/dev/cmr-mini/doc/gameplay/程序默认规则基线.md)
|
||||
- [运行时编译层总表](D:/dev/cmr-mini/doc/gameplay/运行时编译层总表.md)
|
||||
- [玩法设计文档模板](D:/dev/cmr-mini/doc/gameplay/玩法设计文档模板.md)
|
||||
- [玩法构想方案](D:/dev/cmr-mini/doc/gameplay/玩法构想方案.md)
|
||||
- `doc/games/<游戏名称>/规则说明文档.md`
|
||||
- `doc/games/<游戏名称>/游戏说明文档.md`
|
||||
|
||||
作用:
|
||||
|
||||
- 定义客户端自身应该内建的默认行为
|
||||
- 定义某个玩法怎么玩
|
||||
- 定义局流程、状态机、计分、胜负、表现
|
||||
- 明确该玩法选用了哪些公共规则块
|
||||
|
||||
这一层回答的是:
|
||||
|
||||
- 这个玩法的目标是什么
|
||||
- 这个玩法如何开始、推进、结束
|
||||
- 这个玩法和系统公共能力的关系是什么
|
||||
|
||||
### 2.3 玩法配置层
|
||||
|
||||
位置:
|
||||
|
||||
- `doc/games/<游戏名称>/最小配置模板.md`
|
||||
- `doc/games/<游戏名称>/最大配置模板.md`
|
||||
- `doc/games/<游戏名称>/全局配置项.md`
|
||||
- `doc/games/<游戏名称>/游戏配置项.md`
|
||||
- `event/*.json`
|
||||
|
||||
作用:
|
||||
|
||||
- 把玩法规则翻译为可执行配置
|
||||
- 明确这个玩法实际使用的公共字段子集
|
||||
- 给出最小可跑样例和较完整样例
|
||||
|
||||
这一层回答的是:
|
||||
|
||||
- 规则具体落到哪些字段
|
||||
- 哪些字段是系统默认
|
||||
- 哪些字段由玩法覆盖
|
||||
- 当前联调跑的是哪份样例配置
|
||||
|
||||
### 2.4 配置解析层
|
||||
|
||||
位置:
|
||||
|
||||
- [remoteMapConfig.ts](D:/dev/cmr-mini/miniprogram/utils/remoteMapConfig.ts)
|
||||
- [courseToGameDefinition.ts](D:/dev/cmr-mini/miniprogram/game/content/courseToGameDefinition.ts)
|
||||
|
||||
作用:
|
||||
|
||||
- 读取远端或本地 JSON
|
||||
- 补齐模式默认值
|
||||
- 归一化为运行时使用的定义对象
|
||||
|
||||
这一层回答的是:
|
||||
|
||||
- 配置进入程序后如何被解释
|
||||
- 系统默认值何时注入
|
||||
- 不同玩法模式如何做差异化默认处理
|
||||
|
||||
### 2.5 运行时默认与设置层
|
||||
|
||||
位置:
|
||||
|
||||
- [gameModeDefaults.ts](D:/dev/cmr-mini/miniprogram/game/core/gameModeDefaults.ts)
|
||||
- [systemSettingsState.ts](D:/dev/cmr-mini/miniprogram/game/core/systemSettingsState.ts)
|
||||
|
||||
作用:
|
||||
|
||||
- 统一维护玩法默认值
|
||||
- 统一维护设置页默认值
|
||||
- 明确哪些值持久化,哪些锁态不持久化
|
||||
- 为页面层和规则层提供同一套默认基线
|
||||
|
||||
补充约束:
|
||||
|
||||
- 设置值允许玩家修改并持久化
|
||||
- 设置锁态只由系统默认值和活动配置决定
|
||||
- 锁态不持久化,也不允许玩家在页面里切换
|
||||
- 锁态只在当前游戏配置运行生命周期内生效;本局结束或主动退出后失效
|
||||
|
||||
### 2.6 运行时编译层
|
||||
|
||||
位置:
|
||||
|
||||
- [runtimeProfileCompiler.ts](D:/dev/cmr-mini/miniprogram/game/core/runtimeProfileCompiler.ts)
|
||||
- [运行时编译层总表](D:/dev/cmr-mini/doc/gameplay/运行时编译层总表.md)
|
||||
- [故障恢复机制](D:/dev/cmr-mini/doc/gameplay/故障恢复机制.md)
|
||||
|
||||
作用:
|
||||
|
||||
- 统一合并系统默认值、玩法默认值、活动配置和玩家设置
|
||||
- 产出页面、引擎和规则层可直接消费的运行时 profile
|
||||
- 逐步替代页面和引擎中分散的默认值判断
|
||||
|
||||
当前进度:
|
||||
|
||||
- `settings / telemetry / feedback` 已开始走编译层入口
|
||||
- 设置页大部分引擎型设置项已改成统一更新玩家设置,再由编译层回灌引擎
|
||||
- `settings` 当前已通过 `MapEngine.applyCompiledSettingsProfile(...)` 统一落地,不再由页面层散着逐项推送
|
||||
- `presentation` 和一部分 `game` 字段也已开始接入
|
||||
- `map` 也已开始接入地图底座和配置状态这组基础字段
|
||||
- `MapEngine.applyRemoteMapConfig(...)` 已开始退回为原始场地与资源入口
|
||||
|
||||
这一层回答的是:
|
||||
|
||||
- 程序默认值放在哪里
|
||||
- 玩家本地设置如何和系统默认值合并
|
||||
- 锁态为什么不能从历史缓存恢复
|
||||
- 为什么页面、引擎、规则不应再直接各自读原始配置
|
||||
|
||||
### 2.7 故障恢复层
|
||||
|
||||
位置:
|
||||
|
||||
- [sessionRecovery.ts](D:/dev/cmr-mini/miniprogram/game/core/sessionRecovery.ts)
|
||||
- [map.ts](D:/dev/cmr-mini/miniprogram/pages/map/map.ts)
|
||||
- [mapEngine.ts](D:/dev/cmr-mini/miniprogram/engine/map/mapEngine.ts)
|
||||
|
||||
作用:
|
||||
|
||||
- 在对局进行中低频持久化轻量恢复快照
|
||||
- 在异常退出后提供“继续上一局 / 放弃上一局”入口
|
||||
- 只恢复核心运行态,不恢复瞬时 UI
|
||||
|
||||
这一层回答的是:
|
||||
|
||||
- 非正常退出后如何继续比赛
|
||||
- 为什么恢复只保留核心赛局状态
|
||||
- 为什么不尝试恢复白卡、答题卡和动效中间态
|
||||
|
||||
### 2.8 运行时规则层
|
||||
|
||||
位置:
|
||||
|
||||
- [classicSequentialRule.ts](D:/dev/cmr-mini/miniprogram/game/rules/classicSequentialRule.ts)
|
||||
- [scoreORule.ts](D:/dev/cmr-mini/miniprogram/game/rules/scoreORule.ts)
|
||||
- [mapEngine.ts](D:/dev/cmr-mini/miniprogram/engine/map/mapEngine.ts)
|
||||
- [map.ts](D:/dev/cmr-mini/miniprogram/pages/map/map.ts)
|
||||
- [resultSummary.ts](D:/dev/cmr-mini/miniprogram/game/result/resultSummary.ts)
|
||||
- [telemetryRuntime.ts](D:/dev/cmr-mini/miniprogram/game/telemetry/telemetryRuntime.ts)
|
||||
- [playerTelemetryProfile.ts](D:/dev/cmr-mini/miniprogram/game/telemetry/playerTelemetryProfile.ts)
|
||||
|
||||
作用:
|
||||
|
||||
- 根据运行态定义执行状态流转
|
||||
- 响应 GPS、点击、打点、答题、结束等事件
|
||||
- 产出 HUD、反馈、结果页等最终体验
|
||||
- 明确区分可打目标、引导目标、HUD 目标和展示高亮目标
|
||||
|
||||
这一层回答的是:
|
||||
|
||||
- 玩家在游戏中的每一步如何被判定
|
||||
- 积分、答题、结束如何结算
|
||||
- 页面上显示什么、什么时候显示
|
||||
- 活动遥测默认值和玩家身体数据如何合并
|
||||
|
||||
---
|
||||
|
||||
## 3. 规则从设计到运行的链路
|
||||
|
||||
当前实际链路如下:
|
||||
|
||||
1. 在玩法文档里定义默认规则
|
||||
2. 在公共配置文档里定义字段与默认值
|
||||
3. 在玩法目录里确定该玩法使用哪些字段
|
||||
4. 在 `event/*.json` 中写出样例配置
|
||||
5. 由配置解析层读取 JSON 并注入模式默认值
|
||||
6. 由默认值与设置层补齐系统默认行为和玩家本地值
|
||||
7. 由规则引擎和 `MapEngine` 执行游戏逻辑
|
||||
8. 由结果页和 HUD 层展示最终状态
|
||||
|
||||
其中遥测相关链路补充为:
|
||||
|
||||
`系统默认值 -> 活动 telemetry 配置 -> 玩家线上身体数据 -> TelemetryRuntime -> HUD 第 2 页`
|
||||
|
||||
设置相关链路补充为:
|
||||
|
||||
`系统设置默认值 -> 玩家本地持久化值 -> 当前运行时锁态 -> map.ts / MapEngine`
|
||||
|
||||
也可以简化成:
|
||||
|
||||
`规则文档 -> 配置文档 -> 样例 JSON -> 配置解析 -> 规则引擎 -> 运行结果`
|
||||
|
||||
当前已补一层轻量 smoke tests,用于卡住高风险回归:
|
||||
|
||||
- 配置继承
|
||||
- 起点 / 终点规则
|
||||
- 积分赛自由打点
|
||||
- 锁态生命周期
|
||||
- 超时结束
|
||||
|
||||
命令:
|
||||
|
||||
- `npm run test:runtime-smoke`
|
||||
|
||||
---
|
||||
|
||||
## 4. 当前目录分工
|
||||
|
||||
### 4.1 `doc/config`
|
||||
|
||||
职责:
|
||||
|
||||
- 公共配置全集
|
||||
- 公共字段字典
|
||||
- 公共模板
|
||||
- 发布和后台管理方案
|
||||
|
||||
这一层不应该存放某个玩法自己的专属规则文档。
|
||||
|
||||
### 4.2 `doc/gameplay`
|
||||
|
||||
职责:
|
||||
|
||||
- 通用玩法方法论
|
||||
- 玩法设计模板
|
||||
- 玩法构想和规则架构说明
|
||||
|
||||
这一层不应该长期存放具体玩法的正式规则文档。
|
||||
|
||||
### 4.3 `doc/games/<游戏名称>`
|
||||
|
||||
职责:
|
||||
|
||||
- 某个具体玩法的完整文档集合
|
||||
- 玩法说明
|
||||
- 规则说明
|
||||
- 最小 / 最大模板
|
||||
- 全局配置项子集
|
||||
- 游戏配置项子集
|
||||
|
||||
这一层是具体玩法的唯一正式维护入口。
|
||||
|
||||
### 4.4 `event/*.json`
|
||||
|
||||
职责:
|
||||
|
||||
- 当前可运行样例配置
|
||||
- 联调、验证、远端发布的直接输入
|
||||
|
||||
这一层必须和玩法目录中的文档保持一致。
|
||||
|
||||
---
|
||||
|
||||
## 5. 当前已落地的玩法实例
|
||||
|
||||
### 5.1 顺序打点
|
||||
|
||||
正式文档入口:
|
||||
|
||||
- [顺序打点/游戏说明文档](D:/dev/cmr-mini/doc/games/顺序打点/游戏说明文档.md)
|
||||
- [顺序打点/规则说明文档](D:/dev/cmr-mini/doc/games/顺序打点/规则说明文档.md)
|
||||
- [顺序打点/最小配置模板](D:/dev/cmr-mini/doc/games/顺序打点/最小配置模板.md)
|
||||
- [顺序打点/最大配置模板](D:/dev/cmr-mini/doc/games/顺序打点/最大配置模板.md)
|
||||
- [顺序打点/全局配置项](D:/dev/cmr-mini/doc/games/顺序打点/全局配置项.md)
|
||||
- [顺序打点/游戏配置项](D:/dev/cmr-mini/doc/games/顺序打点/游戏配置项.md)
|
||||
- [classic-sequential.json](D:/dev/cmr-mini/event/classic-sequential.json)
|
||||
|
||||
### 5.2 积分赛
|
||||
|
||||
正式文档入口:
|
||||
|
||||
- [积分赛/游戏说明文档](D:/dev/cmr-mini/doc/games/积分赛/游戏说明文档.md)
|
||||
- [积分赛/规则说明文档](D:/dev/cmr-mini/doc/games/积分赛/规则说明文档.md)
|
||||
- [积分赛/最小配置模板](D:/dev/cmr-mini/doc/games/积分赛/最小配置模板.md)
|
||||
- [积分赛/最大配置模板](D:/dev/cmr-mini/doc/games/积分赛/最大配置模板.md)
|
||||
- [积分赛/全局配置项](D:/dev/cmr-mini/doc/games/积分赛/全局配置项.md)
|
||||
- [积分赛/游戏配置项](D:/dev/cmr-mini/doc/games/积分赛/游戏配置项.md)
|
||||
- [score-o.json](D:/dev/cmr-mini/event/score-o.json)
|
||||
|
||||
---
|
||||
|
||||
## 6. 文档与代码同步约定
|
||||
|
||||
后续每次规则变化,建议至少检查 4 层是否同步:
|
||||
|
||||
1. 公共配置文档是否要补字段或默认值
|
||||
2. 对应玩法目录下的规则文档是否要改
|
||||
3. 对应 `event/*.json` 样例是否要改
|
||||
4. 配置解析和规则引擎是否要改
|
||||
|
||||
如果只改了其中一层,就容易出现文档、配置、代码不一致。
|
||||
|
||||
建议统一按下面顺序维护:
|
||||
|
||||
1. 先改规则文档
|
||||
2. 再改配置文档和样例 JSON
|
||||
3. 再改解析代码和规则代码
|
||||
4. 最后回头核对结果页、HUD 和提示是否与文档一致
|
||||
|
||||
---
|
||||
|
||||
## 7. 和后续后台管理的关系
|
||||
|
||||
当前本地项目里,规则主要由文档和样例 JSON 驱动。
|
||||
|
||||
后续接后台后,分工仍然建议保持不变:
|
||||
|
||||
- 玩法文档负责定义规则
|
||||
- 公共配置文档负责定义字段
|
||||
- 后台负责编辑、版本、校验、装配、发布
|
||||
- 客户端继续消费静态 JSON
|
||||
|
||||
也就是说,后台是管理工具,不是规则源头。
|
||||
|
||||
---
|
||||
|
||||
## 8. 一句话总结
|
||||
|
||||
当前这套实际架构可以概括为:
|
||||
|
||||
**`doc/config` 管公共规则全集,`doc/games/<游戏名称>` 管玩法规则与配置子集,`event/*.json` 管可运行样例,客户端解析配置后交给规则引擎执行,并由轻量恢复层处理异常退出后的续局。**
|
||||
411
doc/gameplay/玩法设计文档模板.md
Normal file
411
doc/gameplay/玩法设计文档模板.md
Normal file
@@ -0,0 +1,411 @@
|
||||
# 玩法设计文档模板
|
||||
|
||||
本文档用于定义后续所有玩法设计文档的**统一写法**,保证玩法规则、全局规则块、配置落点和最小样例能够一起沉淀,为后续 JSON 配置管理和后台装配提供稳定输入。
|
||||
|
||||
目标:
|
||||
|
||||
- 统一玩法设计文档结构
|
||||
- 避免只写“玩法创意”,不写“配置落点”
|
||||
- 让后续玩法都能自然接到配置文件和后台管理方案
|
||||
|
||||
说明:
|
||||
|
||||
- 本文档是模板,不是具体玩法规则
|
||||
- 后期 JSON 配置管理以专门后台方案承接
|
||||
- 本文档负责沉淀“设计输入”
|
||||
- 后台方案负责沉淀“编辑、版本、发布、装配”
|
||||
|
||||
建议配合阅读:
|
||||
|
||||
- [全局规则与配置维度清单](D:/dev/cmr-mini/doc/config/全局规则与配置维度清单.md)
|
||||
- [配置选项字典](D:/dev/cmr-mini/doc/config/配置选项字典.md)
|
||||
- [后台配置管理方案V2](D:/dev/cmr-mini/doc/config/后台配置管理方案V2.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. 使用方式
|
||||
|
||||
后续每新增一个玩法,都建议新建一份玩法文档,并按本模板完整填写。
|
||||
|
||||
推荐存放方式:
|
||||
|
||||
- `doc/games/<游戏名称>/游戏说明文档.md`
|
||||
- `doc/games/<游戏名称>/规则说明文档.md`
|
||||
- `doc/games/<游戏名称>/最小配置模板.md`
|
||||
- `doc/games/<游戏名称>/最大配置模板.md`
|
||||
- `doc/games/<游戏名称>/全局配置项.md`
|
||||
- `doc/games/<游戏名称>/游戏配置项.md`
|
||||
|
||||
如果玩法还处于发散阶段,可以先写“构想方案”;
|
||||
一旦进入可开发阶段,就应该补齐本模板里的正式章节。
|
||||
|
||||
---
|
||||
|
||||
## 2. 标准章节清单
|
||||
|
||||
后续每个玩法设计文档,建议至少包含以下章节:
|
||||
|
||||
1. 文档定位
|
||||
2. 一句话规则
|
||||
3. 设计目标
|
||||
4. 适用范围
|
||||
5. 局流程
|
||||
6. 核心对象模型
|
||||
7. 判定与状态机
|
||||
8. 计分与胜负规则
|
||||
9. 全局规则块选型
|
||||
10. 配置落点
|
||||
11. 最小可跑配置样例
|
||||
12. 验收清单
|
||||
13. 后续扩展点
|
||||
|
||||
---
|
||||
|
||||
## 3. 模板正文
|
||||
|
||||
以下为推荐模板正文,可直接复制新建玩法文档后填写。
|
||||
|
||||
---
|
||||
|
||||
# `玩法名称`
|
||||
|
||||
## 1. 文档定位
|
||||
|
||||
本文档用于定义 `玩法模式标识` 的正式规则、默认行为、配置落点和最小可跑样例。
|
||||
|
||||
当前阶段目标:
|
||||
|
||||
- 说明玩法怎么玩
|
||||
- 说明系统如何判定
|
||||
- 说明配置文件如何承载
|
||||
- 说明哪些沿用系统默认,哪些需要玩法覆盖
|
||||
|
||||
---
|
||||
|
||||
## 2. 一句话规则
|
||||
|
||||
请用一句话写清:
|
||||
|
||||
- 玩家要做什么
|
||||
- 怎样推进
|
||||
- 怎样结束
|
||||
- 怎样赢 / 怎样结算
|
||||
|
||||
示例:
|
||||
|
||||
> 玩家需要按顺序完成控制点打卡,允许跳点;普通点打卡后回答限时数学题获取奖励分,打完终点后结算成绩。
|
||||
|
||||
---
|
||||
|
||||
## 3. 设计目标
|
||||
|
||||
建议至少说明:
|
||||
|
||||
- 这个玩法的核心乐趣是什么
|
||||
- 它和已有玩法的主要差异是什么
|
||||
- 它优先验证哪种系统能力
|
||||
|
||||
建议回答:
|
||||
|
||||
- 是否偏竞技
|
||||
- 是否偏探索
|
||||
- 是否偏轻量复玩
|
||||
- 是否偏实时压力
|
||||
|
||||
---
|
||||
|
||||
## 4. 适用范围
|
||||
|
||||
建议至少说明:
|
||||
|
||||
- 适用于单人还是多人
|
||||
- 是否依赖真实 GPS
|
||||
- 是否依赖模拟器
|
||||
- 是否依赖心率等遥测能力
|
||||
- 是否依赖路线型场地还是对象集型场地
|
||||
|
||||
建议落成明确语句:
|
||||
|
||||
- 支持:`单人 / 多人`
|
||||
- 输入依赖:`GPS / 心率 / 模拟输入`
|
||||
- 场地类型:`course / control-set / region-set / object-set`
|
||||
|
||||
---
|
||||
|
||||
## 5. 局流程
|
||||
|
||||
建议按时间顺序写完整流程:
|
||||
|
||||
### 5.1 进入游戏
|
||||
|
||||
- 初始看到什么
|
||||
- 哪些对象显示,哪些隐藏
|
||||
- 是否立即开始计时
|
||||
- 是否先弹提示
|
||||
|
||||
### 5.2 正式开始
|
||||
|
||||
- 什么事件触发正式开局
|
||||
- 是否初始化数据
|
||||
- 是否显示全图 / 全路线
|
||||
- 是否弹开始提示
|
||||
|
||||
### 5.3 进行中推进
|
||||
|
||||
- 玩家如何推进
|
||||
- 当前目标如何变化
|
||||
- 是否允许跳点 / 切目标 / 自由选点
|
||||
- 进行中有哪些关键反馈
|
||||
|
||||
### 5.4 结束
|
||||
|
||||
- 什么条件触发结束
|
||||
- 是否立即停止计时
|
||||
- 是否弹结束提示
|
||||
- 是否进入结算页
|
||||
|
||||
---
|
||||
|
||||
## 6. 核心对象模型
|
||||
|
||||
建议列清玩法运行依赖的对象类型。
|
||||
|
||||
示例格式:
|
||||
|
||||
| 对象类型 | 作用 | 是否必需 | 备注 |
|
||||
| --- | --- | --- | --- |
|
||||
| `start` | 起始触发点 | 是 | 用于正式开赛 |
|
||||
| `control` | 普通推进目标 | 是 | 可按玩法扩展属性 |
|
||||
| `finish` | 结束点 | 视玩法而定 | 用于结束比赛 |
|
||||
| `bonus` | 奖励对象 | 否 | 可选 |
|
||||
| `danger-zone` | 危险区域 | 否 | 可选 |
|
||||
|
||||
还建议说明:
|
||||
|
||||
- 对象来源于 `KML` 还是运行时生成
|
||||
- 对象是静态的还是动态变化的
|
||||
- 对象是否有状态切换
|
||||
|
||||
---
|
||||
|
||||
## 7. 判定与状态机
|
||||
|
||||
### 7.1 局状态
|
||||
|
||||
建议明确列出局状态,例如:
|
||||
|
||||
1. `ready`
|
||||
2. `running`
|
||||
3. `paused`
|
||||
4. `finished`
|
||||
5. `settled`
|
||||
|
||||
### 7.2 关键判定
|
||||
|
||||
建议逐条写清:
|
||||
|
||||
- 打点成功判定
|
||||
- 跳点判定
|
||||
- 得分判定
|
||||
- 失败判定
|
||||
- 完赛判定
|
||||
|
||||
### 7.3 状态切换条件
|
||||
|
||||
建议写成表:
|
||||
|
||||
| 当前状态 | 触发事件 | 下一状态 | 备注 |
|
||||
| --- | --- | --- | --- |
|
||||
| `ready` | 起点打卡成功 | `running` | 正式开始计时 |
|
||||
| `running` | 结束条件满足且终点打卡 | `finished` | 停止计时 |
|
||||
| `finished` | 关闭结束提示 | `settled` | 进入结算页 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 计分与胜负规则
|
||||
|
||||
建议明确:
|
||||
|
||||
- 基础分怎么来
|
||||
- 奖励分怎么来
|
||||
- 扣分怎么来
|
||||
- 跳过点如何处理
|
||||
- 最终成绩显示哪些指标
|
||||
|
||||
推荐格式:
|
||||
|
||||
| 规则项 | 说明 | 默认值 | 备注 |
|
||||
| --- | --- | --- | --- |
|
||||
| 基础分 | 成功打点获得 | `1` | 示例 |
|
||||
| 奖励分 | 答题答对获得 | `1` | 示例 |
|
||||
| 跳过点得分 | 是否得分 | `0` | 示例 |
|
||||
| 结算指标 | 总用时 / 总分 / 成功点数 | - | 示例 |
|
||||
|
||||
如果玩法没有积分,也要写清:
|
||||
|
||||
- 胜负依据是什么
|
||||
- 排名依据是什么
|
||||
- 是否只有完赛状态
|
||||
|
||||
---
|
||||
|
||||
## 9. 全局规则块选型
|
||||
|
||||
本节必须回答“这个玩法用了哪些全局能力块,以及默认选型是什么”。
|
||||
|
||||
建议按下表填写:
|
||||
|
||||
| 规则块 | 是否使用 | 选型 / 配置方向 | 默认值策略 | 备注 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 地图底座 | 是 | 自定义地图 + KML | 沿用系统默认 | |
|
||||
| 点位表现 | 是 | 传统定向紫红系 | 可局部覆盖 | |
|
||||
| 腿线表现 | 是 | `classic-leg` + 动效 | 顺序类沿用默认 | |
|
||||
| 轨迹表现 | 是 | `full` / `tail` / `none` | 玩法指定 | |
|
||||
| 定位点表现 | 是 | `beacon` / `dot` 等 | 沿用系统默认或玩法覆盖 | |
|
||||
| 引导显示 | 是 | 是否显示腿线、是否允许选点 | 玩法指定 | |
|
||||
| 可见性策略 | 是 | 开局隐藏 / 起点后全显 | 玩法指定 | |
|
||||
| 内容体验 | 否 / 是 | 原生 / H5 / 不启用 | 玩法指定 | |
|
||||
| 反馈系统 | 是 | 音效 / 震动 / UI 档位 | 玩法指定 | |
|
||||
| 遥测参数 | 否 / 是 | 是否用心率 | 沿用默认或玩法覆盖 | |
|
||||
| 调试能力 | 是 | 是否开放模拟器 | 开发期指定 | |
|
||||
|
||||
本节的目的不是重复字段字典,而是明确:
|
||||
|
||||
- 这个玩法到底用了哪些公共块
|
||||
- 哪些沿用默认
|
||||
- 哪些要做玩法覆盖
|
||||
|
||||
---
|
||||
|
||||
## 10. 配置落点
|
||||
|
||||
本节用于把规则翻译成配置结构。
|
||||
|
||||
建议写成表:
|
||||
|
||||
| 设计项 | 配置落点 | 是否已有字段 | 默认值 | 是否建议后台表单化 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 起点后显示全路线 | `game.visibility.revealFullPlayfieldAfterStartPunch` | 是 | `true` | 是 |
|
||||
| 跳点开关 | `game.sequence.skip.enabled` | 是 | `true` | 是 |
|
||||
| 答题倒计时 | `待补字段` | 否 | `10` | 先走 JSON 区 |
|
||||
| 目标点样式 | `game.presentation.sequential.controls.current` | 是 | 玩法指定 | 可后续表单化 |
|
||||
|
||||
这里建议把字段分成两类:
|
||||
|
||||
### 10.1 稳定字段
|
||||
|
||||
适合后续做后台正式表单:
|
||||
|
||||
- 模式
|
||||
- 半径
|
||||
- 是否必须起点 / 终点
|
||||
- 是否显示腿线
|
||||
- 是否显示轨迹
|
||||
- 是否允许跳点
|
||||
- 是否启用内容体验
|
||||
|
||||
### 10.2 易变字段
|
||||
|
||||
更适合先放 JSON 编辑区:
|
||||
|
||||
- 实验性计分细则
|
||||
- 特殊答题规则
|
||||
- 视觉实验参数
|
||||
- 单点特殊表现
|
||||
- 复杂状态映射
|
||||
|
||||
本节要和后续后台管理方案衔接,避免字段落点混乱。
|
||||
|
||||
---
|
||||
|
||||
## 11. 最小可跑配置样例
|
||||
|
||||
本节建议给出一个最小可跑 JSON 样例。
|
||||
|
||||
要求:
|
||||
|
||||
- 只保留当前玩法最关键字段
|
||||
- 能作为联调和测试入口
|
||||
- 和规则说明保持一致
|
||||
|
||||
建议结构:
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": "1",
|
||||
"version": "2026.03.31",
|
||||
"app": {},
|
||||
"map": {},
|
||||
"playfield": {},
|
||||
"game": {},
|
||||
"resources": {},
|
||||
"debug": {}
|
||||
}
|
||||
```
|
||||
|
||||
如果已有运行中的 `event/*.json`,应在本节明确引用对应样例。
|
||||
|
||||
---
|
||||
|
||||
## 12. 验收清单
|
||||
|
||||
建议至少覆盖:
|
||||
|
||||
| 验收项 | 是否通过 | 备注 |
|
||||
| --- | --- | --- |
|
||||
| 开局流程与文档一致 | | |
|
||||
| 打点判定与文档一致 | | |
|
||||
| 计分规则与文档一致 | | |
|
||||
| 点位表现与文档一致 | | |
|
||||
| 轨迹与定位点表现一致 | | |
|
||||
| 结算页指标与文档一致 | | |
|
||||
| 样例配置可跑通 | | |
|
||||
| 文档与配置字段口径一致 | | |
|
||||
|
||||
---
|
||||
|
||||
## 13. 后续扩展点
|
||||
|
||||
本节建议专门写:
|
||||
|
||||
- 哪些能力当前先不做
|
||||
- 哪些字段未来可能配置化
|
||||
- 哪些地方后续会交给后台表单化管理
|
||||
|
||||
示例:
|
||||
|
||||
- 第一阶段先固定答题倒计时为 `10` 秒,后续再配置化
|
||||
- 第一阶段先固定基础分 / 奖励分,后续再补 `game.scoring` 细项
|
||||
- 第一阶段样式先走 profile,后续再细化到按状态表单配置
|
||||
|
||||
---
|
||||
|
||||
## 14. 文档产出要求
|
||||
|
||||
后续新增一个正式玩法文档时,建议至少同步产出以下内容:
|
||||
|
||||
1. 一份玩法规则文档
|
||||
2. 一份对应最小样例配置
|
||||
3. 如有新增公共能力,更新 [全局规则与配置维度清单](D:/dev/cmr-mini/doc/config/全局规则与配置维度清单.md)
|
||||
4. 如有新增字段,更新 [配置选项字典](D:/dev/cmr-mini/doc/config/配置选项字典.md)
|
||||
|
||||
---
|
||||
|
||||
## 15. 和后台方案的关系
|
||||
|
||||
后期 JSON 配置文档建议通过专门后台管理,但要注意分工:
|
||||
|
||||
- 玩法文档:
|
||||
负责定义规则、默认值、配置落点、最小样例
|
||||
- 配置字典:
|
||||
负责定义字段含义、可选项和默认值
|
||||
- 后台方案:
|
||||
负责对象、版本、校验、装配、发布
|
||||
|
||||
也就是说:
|
||||
|
||||
**玩法文档是“设计源头”,后台系统是“管理和发布工具”。**
|
||||
|
||||
不要让后台方案反过来决定玩法规则结构。
|
||||
|
||||
|
||||
439
doc/gameplay/程序默认规则基线.md
Normal file
439
doc/gameplay/程序默认规则基线.md
Normal file
@@ -0,0 +1,439 @@
|
||||
# 程序默认规则基线
|
||||
|
||||
本文档用于定义当前客户端在**不依赖活动配置细项**时,程序层应该内建的默认规则。
|
||||
|
||||
目标:
|
||||
|
||||
- 先把程序能力层的默认行为定住
|
||||
- 让代码实现优先对齐这一套基线
|
||||
- 等默认行为稳定后,再决定哪些能力值得开放成配置
|
||||
|
||||
说明:
|
||||
|
||||
- 本文档讲的是**程序默认规则**
|
||||
- 它先于活动配置存在
|
||||
- 它不讨论后台录入方式
|
||||
- 它不追求一次把所有参数开放出去
|
||||
- 当前这批玩法默认值已开始集中收口到 [gameModeDefaults.ts](D:/dev/cmr-mini/miniprogram/game/core/gameModeDefaults.ts)
|
||||
- 设置页默认值与锁态已开始集中收口到 [systemSettingsState.ts](D:/dev/cmr-mini/miniprogram/game/core/systemSettingsState.ts)
|
||||
|
||||
---
|
||||
|
||||
## 1. 总体原则
|
||||
|
||||
当前规则收敛顺序固定为:
|
||||
|
||||
1. 先定程序默认能力
|
||||
2. 再定玩法默认差异
|
||||
3. 最后才开放活动配置覆盖
|
||||
|
||||
程序层默认规则要满足 3 个要求:
|
||||
|
||||
- 默认可玩:不给额外配置也能顺畅跑完一局
|
||||
- 默认统一:相同类型行为在不同玩法下表达一致
|
||||
- 默认克制:不把调试、测试、历史试验行为带进最小流程
|
||||
|
||||
补充一条设置页原则:
|
||||
|
||||
- 设置值和锁态分离管理,避免运行时状态被历史缓存污染
|
||||
|
||||
---
|
||||
|
||||
## 2. 程序默认层次
|
||||
|
||||
前台默认只保留 5 类可见反馈层。
|
||||
|
||||
同时,程序默认值分成两条并行基线:
|
||||
|
||||
- 对局规则默认值
|
||||
- 系统设置默认值
|
||||
|
||||
### 2.1 黑底引导提示条
|
||||
|
||||
职责:
|
||||
|
||||
- 只负责告诉玩家“下一步该做什么”
|
||||
|
||||
规则:
|
||||
|
||||
- 自动消失
|
||||
- 可手动关闭
|
||||
- 文案变化时可有轻动画
|
||||
- 默认只配轻震动
|
||||
- 不承担结果反馈
|
||||
- 不承担内容说明
|
||||
|
||||
### 2.2 彩色短反馈条
|
||||
|
||||
职责:
|
||||
|
||||
- 只负责告诉玩家“刚刚发生了什么”
|
||||
|
||||
规则:
|
||||
|
||||
- 短暂出现
|
||||
- 不带按钮
|
||||
- 不显示长说明
|
||||
- 不承担下一步引导
|
||||
|
||||
### 2.3 白色内容卡
|
||||
|
||||
职责:
|
||||
|
||||
- 只承载显式配置的点位内容
|
||||
|
||||
规则:
|
||||
|
||||
- 默认不进入最小流程
|
||||
- 默认关闭
|
||||
- 仅当某个点位明确启用时才参与流程
|
||||
- 浏览型卡片默认短时自动消失
|
||||
- 交互型卡片只在显式开启时出现
|
||||
|
||||
### 2.4 答题卡
|
||||
|
||||
职责:
|
||||
|
||||
- 承载显式启用的答题玩法
|
||||
|
||||
规则:
|
||||
|
||||
- 属于强交互层
|
||||
- 最小模板下默认关闭
|
||||
- 仅当点位显式配置 `quiz` CTA 时才进入
|
||||
- 不依赖白色内容卡作为前置
|
||||
|
||||
### 2.5 成绩总览页
|
||||
|
||||
职责:
|
||||
|
||||
- 承载结算结果
|
||||
|
||||
规则:
|
||||
|
||||
- 终点完成后直接进入
|
||||
- 不再额外叠终点白卡
|
||||
|
||||
---
|
||||
|
||||
## 3. 打点默认规则
|
||||
|
||||
### 3.1 开始点
|
||||
|
||||
程序默认行为:
|
||||
|
||||
- 必须先打开始点才能正式开赛
|
||||
- 成功打开始点后开始计时
|
||||
- 起点完成后只给短反馈,并更新引导和 HUD
|
||||
- 默认不弹白色开始卡
|
||||
- 默认不弹答题卡
|
||||
|
||||
### 3.2 普通点
|
||||
|
||||
程序默认行为:
|
||||
|
||||
- 成功打点后先完成基础结算
|
||||
- 最小模板下默认不弹答题卡
|
||||
- 如需答题,必须显式配置点位 CTA
|
||||
- 默认不先弹白色内容卡
|
||||
- 默认不重复得分
|
||||
- 默认不重复出题
|
||||
|
||||
### 3.3 结束点
|
||||
|
||||
程序默认行为:
|
||||
|
||||
- 成功打终点后先给完成短反馈
|
||||
- 随后直接进入结果页
|
||||
- 默认不弹白色终点卡
|
||||
- 默认不弹答题卡
|
||||
|
||||
### 3.4 关门时间
|
||||
|
||||
程序默认行为:
|
||||
|
||||
- 默认关门时间为开赛后 `2` 小时
|
||||
- 距离关门时间小于等于 `10` 分钟时,HUD 第 1 页时间区切换为倒计时显示
|
||||
- 倒计时显示需有区别于正常计时的强调样式
|
||||
- 到达关门时间后,系统自动结束当前对局
|
||||
- 超时结束必须和正常完赛、主动退出区分开
|
||||
|
||||
---
|
||||
|
||||
## 4. 玩法默认差异
|
||||
|
||||
程序只内建少量玩法差异,不把所有东西做成配置。
|
||||
|
||||
### 4.1 顺序打点 `classic-sequential`
|
||||
|
||||
默认差异:
|
||||
|
||||
- 按顺序推进
|
||||
- 默认允许跳点
|
||||
- 默认跳点半径 = 打点半径的 2 倍
|
||||
- 默认跳点前弹出确认
|
||||
- 当前目标点由系统自动推进
|
||||
- 终点默认需要在中间点都“成功或跳过”后才生效
|
||||
- 普通点基础分默认 `1`
|
||||
- 普通点默认不附带答题奖励
|
||||
|
||||
### 4.2 积分赛 `score-o`
|
||||
|
||||
默认差异:
|
||||
|
||||
- 自由打点
|
||||
- 默认不存在跳点
|
||||
- 默认不要求先选中目标点
|
||||
- 点击某个积分点时,默认只更新当前目标和 HUD 信息
|
||||
- 未点击选中时,也允许直接进入任意积分点范围完成打点
|
||||
- 默认至少完成 `1` 个普通积分点后,终点才解锁
|
||||
- 普通点基础分默认取该点分值
|
||||
- 普通点默认不附带答题奖励
|
||||
|
||||
---
|
||||
|
||||
## 5. HUD 默认规则
|
||||
|
||||
HUD 属于公共程序能力,不属于某个玩法专属实现。
|
||||
|
||||
### 5.1 固定结构
|
||||
|
||||
- HUD 固定为 2 页
|
||||
- 第 1 页为比赛主信息页
|
||||
- 第 2 页为心率 / 遥测页
|
||||
- 异型壳子布局固定,不因玩法改变结构
|
||||
|
||||
### 5.2 第 1 页默认职责
|
||||
|
||||
- 时间
|
||||
- 里程
|
||||
- 动作标签
|
||||
- 目标摘要
|
||||
- 目标距离
|
||||
- 进度摘要
|
||||
- 速度
|
||||
- 临近关门时间时,时间槽位切换为倒计时
|
||||
|
||||
### 5.3 第 2 页默认职责
|
||||
|
||||
- 心率
|
||||
- 卡路里
|
||||
- 平均速度
|
||||
- 精度或相关遥测值
|
||||
|
||||
### 5.4 遥测身体数据来源
|
||||
|
||||
程序默认口径:
|
||||
|
||||
- HUD 第 2 页使用统一遥测运行时
|
||||
- 活动配置里的 `game.telemetry.*` 只作为活动默认值
|
||||
- 玩家年龄、静息心率、体重等身体数据,后续允许由线上接口覆盖
|
||||
- 线上身体数据一旦到位,应高于活动配置生效
|
||||
|
||||
默认优先级:
|
||||
|
||||
`系统默认值 -> 活动遥测默认值 -> 玩家线上身体数据`
|
||||
|
||||
### 5.5 玩法映射默认口径
|
||||
|
||||
- 顺序打点:
|
||||
- 目标摘要显示当前目标点
|
||||
- 进度摘要显示完成进度和跳点数
|
||||
- 积分赛:
|
||||
- 目标摘要显示当前选中目标点
|
||||
- 进度摘要显示总分和收集进度
|
||||
|
||||
### 5.6 目标角色默认口径
|
||||
|
||||
程序默认把目标拆成 4 类:
|
||||
|
||||
- 可打目标:当前进入范围后可真正完成打点的对象
|
||||
- 引导目标:用于距离音效、接近提示和弱引导的对象
|
||||
- HUD 目标:用于底部信息面板距离与摘要显示的对象
|
||||
- 展示高亮目标:用于地图上重点高亮的对象
|
||||
|
||||
约束:
|
||||
|
||||
- 这 4 类目标不能再混用
|
||||
- 积分赛里“选中目标”默认只影响 HUD 目标
|
||||
- 距离音效默认只跟随引导目标,不跟随选中状态
|
||||
|
||||
---
|
||||
|
||||
## 6. 距离反馈默认规则
|
||||
|
||||
距离反馈和黑底引导提示条分离管理。
|
||||
|
||||
### 6.1 黑底引导提示条
|
||||
|
||||
- 默认只走轻震动
|
||||
- 不绑定提示音
|
||||
|
||||
### 6.2 距离提示
|
||||
|
||||
默认分为 3 档:
|
||||
|
||||
1. `distant`
|
||||
2. `approaching`
|
||||
3. `ready`
|
||||
|
||||
默认口径:
|
||||
|
||||
- `ready`:进入可打点范围
|
||||
- `approaching`:接近目标
|
||||
- `distant`:较远但仍处于有效提醒范围
|
||||
- 更远距离默认静默
|
||||
|
||||
默认阈值:
|
||||
|
||||
- `distantDistanceMeters = 80`
|
||||
- `approachDistanceMeters = 20`
|
||||
- `readyDistanceMeters = 5`
|
||||
|
||||
默认节奏:
|
||||
|
||||
- `distant`:弱提醒,默认间隔 `4800ms`
|
||||
- `approaching`:较明确提醒,默认间隔 `950ms`
|
||||
- `ready`:确认提醒,默认间隔 `650ms`
|
||||
|
||||
---
|
||||
|
||||
## 7. 系统设置默认规则
|
||||
|
||||
设置页属于程序公共能力,不属于某个玩法专属逻辑。
|
||||
|
||||
### 7.1 设置项结构
|
||||
|
||||
每个设置项默认由两部分组成:
|
||||
|
||||
- `value`:设置值
|
||||
- `isLocked`:是否允许玩家修改
|
||||
|
||||
### 7.2 默认值规则
|
||||
|
||||
程序默认要求:
|
||||
|
||||
- 每个设置项都必须有系统默认值
|
||||
- 玩家未手动修改时,直接使用系统默认值
|
||||
- 默认值应集中维护,不散落在页面逻辑里
|
||||
|
||||
### 7.3 持久化规则
|
||||
|
||||
程序默认要求:
|
||||
|
||||
- `value` 需要持久化
|
||||
- `isLocked` 不持久化
|
||||
- 页面每次进入时,锁态都应重新按当前运行时规则计算
|
||||
- 锁态只受系统默认值与活动配置影响,玩家不能在页面中修改锁态
|
||||
- 设置页中的锁态徽标只做状态展示,不提供点按切换能力
|
||||
- 锁态生存期:从当前游戏配置载入并进入该局开始,到本局正常结束、超时结束或主动退出为止
|
||||
|
||||
默认优先级:
|
||||
|
||||
`系统设置默认值 -> 玩家本地持久化值`
|
||||
|
||||
锁态优先级:
|
||||
|
||||
`系统锁态默认值 -> 当前运行时或活动规则覆盖`
|
||||
|
||||
### 7.4 当前已集中维护的设置基线
|
||||
|
||||
当前已在 [systemSettingsState.ts](D:/dev/cmr-mini/miniprogram/game/core/systemSettingsState.ts) 集中维护:
|
||||
|
||||
- 轨迹显示
|
||||
- GPS 点显示
|
||||
- 侧边按钮习惯
|
||||
- 自动旋转
|
||||
- 指北针调校
|
||||
- 北向参考
|
||||
- 中央标尺显示与锚点
|
||||
- 各设置项的默认锁态
|
||||
|
||||
---
|
||||
|
||||
## 8. 最小流程基线
|
||||
|
||||
### 8.1 顺序打点最小流程
|
||||
|
||||
1. 进入游戏,只显示开始点
|
||||
2. 打开始点,开赛并显示全场
|
||||
3. 按顺序推进普通点
|
||||
4. 普通点打点后默认只做基础结算
|
||||
5. 可触发跳点
|
||||
6. 打终点后直接进入结果页
|
||||
7. 如果超过 `2` 小时仍未结束,系统按超时结束处理
|
||||
|
||||
### 8.2 积分赛最小流程
|
||||
|
||||
1. 进入游戏,只显示开始点
|
||||
2. 打开始点,开赛并显示全部积分点和终点
|
||||
3. 可直接前往任意积分点,或点击某个点更新当前目标
|
||||
4. 进入积分点范围后成功打点
|
||||
5. 普通点打点后默认只做基础结算
|
||||
6. 默认至少完成 `1` 个普通积分点后可打终点结束
|
||||
7. 如果超过 `2` 小时仍未结束,系统按超时结束处理
|
||||
|
||||
---
|
||||
|
||||
## 9. 暂不开放为配置的内容
|
||||
|
||||
当前先不优先配置化的内容:
|
||||
|
||||
- 弹层体系层级
|
||||
- 起点是否弹白卡
|
||||
- 普通点是否先白卡后答题
|
||||
- 终点是否白卡后结算
|
||||
- HUD 是否双页
|
||||
- HUD 异型壳子结构
|
||||
- 黑条提示与距离反馈的职责边界
|
||||
|
||||
这些内容应先作为程序默认能力稳定下来。
|
||||
|
||||
---
|
||||
|
||||
## 10. 故障恢复基线
|
||||
|
||||
当前故障恢复按“轻量快照恢复”处理:
|
||||
|
||||
- 仅恢复进行中的对局
|
||||
- 仅恢复核心赛局状态、遥测累计值和地图基础视口
|
||||
- 不恢复白卡、答题卡、临时动效、短反馈和提示层
|
||||
- 恢复后由规则层和展示层重新计算 HUD、按钮文案、目标提示和音效状态
|
||||
|
||||
当前默认恢复内容:
|
||||
|
||||
- 当前配置入口
|
||||
- `startedAt / completedControlIds / skippedControlIds / currentTargetControlId / score / modeState`
|
||||
- 累计里程、基础心率/卡路里累计、最后 GPS 点
|
||||
- `zoom / centerTile / rotation / gpsLock`
|
||||
|
||||
当前默认不恢复内容:
|
||||
|
||||
- 详情卡
|
||||
- 答题中间态
|
||||
- 待查看内容入口
|
||||
- 所有瞬时动效和提示队列
|
||||
|
||||
---
|
||||
|
||||
## 11. 后续开放配置的原则
|
||||
|
||||
后续只有满足以下条件的内容,才建议开放成配置:
|
||||
|
||||
- 运营确实会频繁改
|
||||
- 改动不会破坏主流程一致性
|
||||
- 改完不会引入一组新的层级冲突
|
||||
|
||||
优先可配置的内容应是:
|
||||
|
||||
- 点位分值
|
||||
- 点位内容是否启用
|
||||
- 点位样式
|
||||
- 三档距离提示阈值
|
||||
- 三档距离提示间隔
|
||||
|
||||
---
|
||||
|
||||
## 12. 一句话结论
|
||||
|
||||
当前阶段应以这份文档作为**程序默认能力基线**:先把最小流程、弹层职责、HUD 结构和距离反馈定死,再决定哪些内容值得进入配置层。
|
||||
245
doc/gameplay/运行时编译层总表.md
Normal file
245
doc/gameplay/运行时编译层总表.md
Normal file
@@ -0,0 +1,245 @@
|
||||
# 运行时编译层总表
|
||||
|
||||
本文档用于定义当前项目推荐的“运行时编译层”结构,也就是把系统默认值、玩法默认值、活动配置、玩家设置编译成统一运行时 profile 的中间层。
|
||||
|
||||
目标:
|
||||
|
||||
- 避免页面、引擎、规则层到处直接读取原始配置
|
||||
- 明确各种默认值和覆盖值的合并顺序
|
||||
- 为后续继续收口代码提供统一目标
|
||||
|
||||
说明:
|
||||
|
||||
- 本文档讲的是“运行时编译结构”
|
||||
- 它不替代字段字典和玩法规则文档
|
||||
- 当前已先落第一版代码骨架,后续会逐步把更多模块并到这一层
|
||||
|
||||
---
|
||||
|
||||
## 1. 为什么需要编译层
|
||||
|
||||
当前系统里至少有 4 类来源:
|
||||
|
||||
1. 系统默认值
|
||||
2. 玩法默认值
|
||||
3. 活动配置
|
||||
4. 玩家设置
|
||||
|
||||
如果页面、引擎、规则层分别自己去判断这些来源,问题会很快出现:
|
||||
|
||||
- 默认值散落
|
||||
- 覆盖顺序不一致
|
||||
- 同一个字段在不同页面里表现不同
|
||||
- 后续后台接入后更难维护
|
||||
|
||||
所以推荐做法是:
|
||||
|
||||
先编译,再运行。
|
||||
|
||||
也就是:
|
||||
|
||||
`默认值 / 配置 / 玩家设置 -> Runtime Profile -> MapEngine / Rule / HUD`
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前推荐编译顺序
|
||||
|
||||
### 2.1 规则与玩法相关
|
||||
|
||||
推荐顺序:
|
||||
|
||||
`系统默认值 -> 玩法默认值 -> 活动配置`
|
||||
|
||||
适用:
|
||||
|
||||
- 对局流程
|
||||
- 打点规则
|
||||
- 跳点规则
|
||||
- 完赛规则
|
||||
- 分值默认值
|
||||
|
||||
### 2.2 系统设置相关
|
||||
|
||||
推荐顺序:
|
||||
|
||||
`系统设置默认值 -> 活动 settings 默认值 -> 玩家本地设置值`
|
||||
|
||||
锁态单独处理:
|
||||
|
||||
`系统默认锁态 -> 活动 settings 锁态 -> 本局锁态生命周期`
|
||||
|
||||
说明:
|
||||
|
||||
- 设置值可以持久化
|
||||
- 锁态不持久化
|
||||
- 锁态只在当前游戏配置运行生命周期内生效
|
||||
|
||||
### 2.3 遥测相关
|
||||
|
||||
推荐顺序:
|
||||
|
||||
`系统遥测默认值 -> 活动 telemetry 默认值 -> 玩家身体数据`
|
||||
|
||||
适用:
|
||||
|
||||
- 年龄
|
||||
- 静息心率
|
||||
- 体重
|
||||
|
||||
---
|
||||
|
||||
## 3. 当前推荐 profile 结构
|
||||
|
||||
当前建议至少编译成以下几块:
|
||||
|
||||
### 3.1 `map`
|
||||
|
||||
负责地图底座级运行参数:
|
||||
|
||||
- 标题
|
||||
- 控制点绘制半径
|
||||
- 投影
|
||||
- 磁偏角
|
||||
- 初始缩放
|
||||
|
||||
### 3.2 `game`
|
||||
|
||||
负责玩法与规则层运行参数:
|
||||
|
||||
- 玩法模式
|
||||
- 关门时间
|
||||
- 关门预警时间
|
||||
- 打点方式
|
||||
- 打点半径
|
||||
- 是否先选目标点
|
||||
- 是否允许跳点
|
||||
- 跳点半径
|
||||
- 跳点确认
|
||||
- 是否自动结束
|
||||
- 默认点位分值
|
||||
|
||||
### 3.3 `settings`
|
||||
|
||||
负责系统设置页相关运行参数:
|
||||
|
||||
- 设置值最终结果
|
||||
- 锁态最终结果
|
||||
- 锁态生命周期是否激活
|
||||
|
||||
### 3.4 `telemetry`
|
||||
|
||||
负责遥测层运行参数:
|
||||
|
||||
- 合并后的遥测配置
|
||||
- 当前玩家身体数据快照
|
||||
|
||||
### 3.5 `presentation`
|
||||
|
||||
负责表现层 profile:
|
||||
|
||||
- 控制点样式
|
||||
- 轨迹样式
|
||||
- GPS 点样式
|
||||
|
||||
### 3.6 `feedback`
|
||||
|
||||
负责反馈层 profile:
|
||||
|
||||
- 音效配置
|
||||
- 震动配置
|
||||
- UI 动效配置
|
||||
|
||||
---
|
||||
|
||||
## 4. 当前代码落点
|
||||
|
||||
第一版运行时编译骨架已落在:
|
||||
|
||||
- [runtimeProfileCompiler.ts](D:/dev/cmr-mini/miniprogram/game/core/runtimeProfileCompiler.ts)
|
||||
|
||||
当前已经开始编译的内容:
|
||||
|
||||
- `game`
|
||||
- `settings`
|
||||
- `telemetry`
|
||||
- `presentation`
|
||||
- `feedback`
|
||||
- `map`
|
||||
|
||||
当前已接入页面 / 引擎的部分:
|
||||
|
||||
- 设置页运行时 profile
|
||||
- 遥测层运行时 profile
|
||||
- 反馈层运行时 profile
|
||||
- 表现层 runtime profile
|
||||
- 规则层中一部分 `game profile` 字段
|
||||
|
||||
当前接入说明:
|
||||
|
||||
- `settings / telemetry / feedback` 已开始作为日常运行入口使用
|
||||
- 设置页大部分引擎型设置项已改成“先更新玩家设置,再统一走 `settings profile` 回灌 `MapEngine`”
|
||||
- `settings profile` 现已通过 `MapEngine.applyCompiledSettingsProfile(...)` 统一应用,不再由页面逐项调用各类 `handleSet...`
|
||||
- `presentation` 已开始通过编译层回写 `MapEngine` 表现参数
|
||||
- `game` 当前已先接入模式、关门时间、打点和跳点这组核心字段
|
||||
- `map` 已开始接入地图底座参数和配置状态文本这组基础字段
|
||||
- `MapEngine.applyRemoteMapConfig(...)` 已开始退回为原始场地与资源入口,不再继续双写已编译字段
|
||||
|
||||
后续建议继续并入:
|
||||
|
||||
- `MapEngine.applyRemoteMapConfig(...)` 的配置归一入口
|
||||
- `map profile`
|
||||
- 更多 `game profile` 字段
|
||||
- `courseToGameDefinition`
|
||||
|
||||
---
|
||||
|
||||
## 5. 当前推荐落地步骤
|
||||
|
||||
建议按以下顺序继续收代码:
|
||||
|
||||
1. 先让剩余设置层完全只吃 `settings profile`
|
||||
2. 再让遥测层只吃 `telemetry profile`
|
||||
3. 再让反馈层只吃 `feedback profile`
|
||||
4. 最后把玩法规则入口和表现入口都改成吃统一 profile
|
||||
|
||||
补充:
|
||||
|
||||
- 规则层中的目标角色也应尽量由统一运行态承载,而不是散落在 HUD 和地图展示字段里反推
|
||||
- 当前已先明确 4 类目标角色:
|
||||
- 可打目标
|
||||
- 引导目标
|
||||
- HUD 目标
|
||||
- 展示高亮目标
|
||||
|
||||
这样风险最小,也最容易逐步验证。
|
||||
|
||||
---
|
||||
|
||||
## 6. 这层的边界
|
||||
|
||||
运行时编译层应该只做两件事:
|
||||
|
||||
1. 合并来源
|
||||
2. 产出最终运行态 profile
|
||||
|
||||
不应该做的事:
|
||||
|
||||
- 不直接承载页面状态
|
||||
- 不直接承载本局临时分数和目标点
|
||||
- 不直接写回配置
|
||||
- 不承担玩法执行逻辑本身
|
||||
|
||||
也就是说:
|
||||
|
||||
- 编译层负责“准备好”
|
||||
- 引擎和规则层负责“执行”
|
||||
|
||||
---
|
||||
|
||||
## 7. 当前结论
|
||||
|
||||
后续推荐统一按这条链走:
|
||||
|
||||
`系统默认值 -> 玩法默认值 -> 活动配置 -> 玩家设置 -> 运行时编译层 -> 引擎 / 页面 / 规则`
|
||||
|
||||
这样配置越多,系统越不容易乱;后续后台做复杂了,也还是有一层中间结构兜住。
|
||||
Reference in New Issue
Block a user