chore: 提交调试文档与模拟器改动
This commit is contained in:
338
doc/config/线上业务接入边界方案.md
Normal file
338
doc/config/线上业务接入边界方案.md
Normal file
@@ -0,0 +1,338 @@
|
||||
# 线上业务接入边界方案
|
||||
|
||||
## 1. 目的
|
||||
|
||||
本文档定义小程序接入线上业务 API 时的架构边界,确保以下原则始终成立:
|
||||
|
||||
- 游戏玩法仍然完全由配置驱动
|
||||
- 线上 API 只负责业务编排,不负责定义或污染玩法
|
||||
- 地图引擎和规则运行时可以继续独立于业务系统运行
|
||||
- 本地 demo、离线配置、线上赛事三种入口可以共存
|
||||
|
||||
本文档适用于以下接入范围:
|
||||
|
||||
- 用户管理
|
||||
- 登录与鉴权
|
||||
- 首页卡片
|
||||
- 赛事详情
|
||||
- 地图详情
|
||||
- Event 详情
|
||||
- 报名
|
||||
- launch 启动
|
||||
- 后续 session 上报与查询
|
||||
|
||||
## 2. 核心结论
|
||||
|
||||
线上接入后,系统仍保持两层结构:
|
||||
|
||||
- 业务层:决定“用户是谁、能进什么、当前启动什么”
|
||||
- 游戏层:决定“地图怎么画、规则怎么跑、控制点怎么判定、体验怎么表现”
|
||||
|
||||
两层之间只允许通过一个明确的启动模型通信,不允许业务 API 对游戏规则对象做直接写入。
|
||||
|
||||
一句话定义:
|
||||
|
||||
> API 负责发放启动上下文,配置负责定义游戏本身。
|
||||
|
||||
## 3. 分层原则
|
||||
|
||||
### 3.1 业务层职责
|
||||
|
||||
业务层负责:
|
||||
|
||||
- 登录与 token 管理
|
||||
- 用户资料与身体数据
|
||||
- 卡片、赛事、地图、Event 列表与详情
|
||||
- 报名资格校验
|
||||
- launch 启动资格与 session 凭证发放
|
||||
- 后续成绩、轨迹、历史记录上传与查询
|
||||
|
||||
业务层可以决定:
|
||||
|
||||
- 是否允许用户启动
|
||||
- 当前应启动哪个 Event
|
||||
- 当前应加载哪份配置或 manifest
|
||||
- 当前启动绑定的 `session_id`、`session_token`
|
||||
|
||||
业务层不可以决定:
|
||||
|
||||
- 控制点布局
|
||||
- 游戏规则
|
||||
- 打卡判定
|
||||
- 跳点规则
|
||||
- 引导、音效、表现策略
|
||||
- 游戏内内容卡的结构和行为定义
|
||||
|
||||
### 3.2 游戏层职责
|
||||
|
||||
游戏层负责:
|
||||
|
||||
- 地图资源加载
|
||||
- KML / course / 配置解析
|
||||
- `GameDefinition` 构建
|
||||
- 规则插件运行
|
||||
- 传感器接入
|
||||
- HUD、反馈、结果页、本地统计
|
||||
- 游戏内 session 生命周期
|
||||
|
||||
游戏层只认配置和本地运行态,不认业务 API 对象。
|
||||
|
||||
游戏层不应该直接出现以下业务字段:
|
||||
|
||||
- `competition_id`
|
||||
- `registration_status`
|
||||
- `access_token`
|
||||
- `refresh_token`
|
||||
- `Authorization`
|
||||
- `user_id`
|
||||
|
||||
业务字段可以存在于页面壳层或业务服务层,但不进入规则层。
|
||||
|
||||
## 4. 唯一允许的层间模型
|
||||
|
||||
业务层和游戏层之间,统一通过 `GameLaunchEnvelope` 通信。
|
||||
|
||||
建议结构如下:
|
||||
|
||||
```ts
|
||||
interface GameLaunchEnvelope {
|
||||
config: {
|
||||
configUrl: string
|
||||
configLabel: string
|
||||
configChecksumSha256?: string | null
|
||||
releaseId?: string | null
|
||||
routeCode?: string | null
|
||||
}
|
||||
business: {
|
||||
source: 'demo' | 'competition' | 'direct-event' | 'custom'
|
||||
competitionId?: string | null
|
||||
eventId?: string | null
|
||||
launchRequestId?: string | null
|
||||
participantId?: string | null
|
||||
sessionId?: string | null
|
||||
sessionToken?: string | null
|
||||
sessionTokenExpiresAt?: string | null
|
||||
realtimeEndpoint?: string | null
|
||||
realtimeToken?: string | null
|
||||
} | null
|
||||
}
|
||||
```
|
||||
|
||||
解释:
|
||||
|
||||
- `config` 是游戏层真正消费的输入
|
||||
- `business` 是业务壳保留的上下文
|
||||
- 地图页可以同时拿到两者,但地图引擎只读取 `config`
|
||||
|
||||
## 5. 推荐启动链路
|
||||
|
||||
### 5.1 Demo 启动
|
||||
|
||||
适用于本地调试、离线测试、玩法验证。
|
||||
|
||||
流程:
|
||||
|
||||
1. 页面构建 demo `GameLaunchEnvelope`
|
||||
2. `config.configUrl` 指向 demo 配置
|
||||
3. `business.source = 'demo'`
|
||||
4. 跳转地图页
|
||||
5. 地图页加载配置并启动引擎
|
||||
|
||||
特点:
|
||||
|
||||
- 不依赖业务 API
|
||||
- 不依赖登录
|
||||
- 不依赖 session
|
||||
|
||||
### 5.2 线上赛事启动
|
||||
|
||||
适用于正式业务入口。
|
||||
|
||||
流程:
|
||||
|
||||
1. 业务页请求赛事 / Event 详情
|
||||
2. 用户在业务页完成登录、资格校验、报名确认
|
||||
3. 用户点击开始,业务页调用 `launch`
|
||||
4. 后端返回 `session_id`、`session_token`、`release_id`、`manifest_url`、`route_code`
|
||||
5. 业务层把上述信息转换为 `GameLaunchEnvelope`
|
||||
6. 地图页只根据 `config` 载入配置
|
||||
7. 业务壳层保存 `business` 上下文供后续上报使用
|
||||
|
||||
注意:
|
||||
|
||||
- `launch` 是业务启动,不等于规则层 `startSession`
|
||||
- 规则层本地开始游戏,仍由引擎按配置驱动
|
||||
|
||||
### 5.3 线上直入地图启动
|
||||
|
||||
适用于地图详情或 Event 直入。
|
||||
|
||||
流程与赛事入口基本一致,区别仅在于:
|
||||
|
||||
- 入口页不同
|
||||
- 资格校验更轻
|
||||
- `business.source = 'direct-event'`
|
||||
|
||||
## 6. manifest 的角色
|
||||
|
||||
后端提供的 `manifest_url` 不应直接变成规则层对象。
|
||||
|
||||
推荐做法:
|
||||
|
||||
- 业务层或适配层下载 manifest
|
||||
- 将 manifest 解析并映射到当前配置体系
|
||||
- 输出为当前引擎已支持的配置入口
|
||||
|
||||
manifest 是“线上发布描述”,不是“规则运行对象”。
|
||||
|
||||
建议把 manifest 适配理解为一个编译过程:
|
||||
|
||||
- 输入:后端发布描述
|
||||
- 输出:当前配置驱动引擎可识别的配置资源
|
||||
|
||||
## 7. 目录建议
|
||||
|
||||
建议按三层组织代码:
|
||||
|
||||
```text
|
||||
miniprogram/
|
||||
services/
|
||||
http.ts
|
||||
client-api.ts
|
||||
auth.ts
|
||||
business/
|
||||
launch/
|
||||
launchBuilder.ts
|
||||
launchStore.ts
|
||||
manifestAdapter.ts
|
||||
utils/
|
||||
gameLaunch.ts
|
||||
pages/
|
||||
login/
|
||||
home/
|
||||
competition-detail/
|
||||
event-detail/
|
||||
map/
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `services` 只处理 API 通信
|
||||
- `business/launch` 只做业务到配置的适配
|
||||
- `utils/gameLaunch.ts` 定义启动模型和页面跳转协议
|
||||
- `pages/map` 只做配置加载和游戏承载
|
||||
|
||||
## 8. 代码边界约束
|
||||
|
||||
### 8.1 允许进入地图页的内容
|
||||
|
||||
允许进入地图页:
|
||||
|
||||
- `GameLaunchEnvelope`
|
||||
- `configUrl`
|
||||
- `configLabel`
|
||||
- `releaseId`
|
||||
- `routeCode`
|
||||
- `sessionToken`
|
||||
|
||||
但地图页内部还要继续区分:
|
||||
|
||||
- 引擎可读:`config`
|
||||
- 业务壳可读:`business`
|
||||
|
||||
### 8.2 不允许进入引擎的内容
|
||||
|
||||
以下内容禁止进入 `MapEngine`、`GameRuntime`、`GameDefinition`:
|
||||
|
||||
- 用户信息
|
||||
- 登录态 token
|
||||
- 报名状态
|
||||
- 业务接口返回原始对象
|
||||
- 赛事详情原始 JSON
|
||||
- Event 详情原始 JSON
|
||||
|
||||
### 8.3 上报也走旁路
|
||||
|
||||
后续若接 `punches`、`finish`、`session-uploads`,建议流程如下:
|
||||
|
||||
1. 游戏层产生本地事件
|
||||
2. 页面壳层或业务 service 订阅这些事件
|
||||
3. 由业务层决定是否调用 API
|
||||
|
||||
不要在规则层里直接 `wx.request`。
|
||||
|
||||
## 9. 当前项目的落地点
|
||||
|
||||
当前项目已具备以下基础:
|
||||
|
||||
- 地图页是配置驱动入口
|
||||
- `remoteMapConfig.ts` 负责远程配置加载
|
||||
- `MapEngine` 负责本地规则与表现运行
|
||||
- 已新增 `utils/gameLaunch.ts` 作为启动边界模型
|
||||
|
||||
当前建议继续保持:
|
||||
|
||||
- `MapEngine` 只接 `RemoteMapConfig`
|
||||
- 地图页只从 `GameLaunchEnvelope.config` 获取配置入口
|
||||
- 业务上下文保留在地图页外层或页面壳层
|
||||
|
||||
## 10. 分阶段落地建议
|
||||
|
||||
### 阶段一:边界固化
|
||||
|
||||
目标:
|
||||
|
||||
- 地图页彻底改为只接 `GameLaunchEnvelope`
|
||||
- demo 启动与线上启动走同一套入口协议
|
||||
|
||||
验收标准:
|
||||
|
||||
- 不再依赖页面内硬编码 URL 作为唯一启动方式
|
||||
- 业务字段不进入引擎
|
||||
|
||||
### 阶段二:业务壳接入
|
||||
|
||||
目标:
|
||||
|
||||
- 接入登录、首页卡片、赛事详情、Event 详情、报名、launch
|
||||
|
||||
验收标准:
|
||||
|
||||
- 能从业务页成功进入地图页
|
||||
- 地图仍由配置驱动启动
|
||||
|
||||
### 阶段三:manifest 适配
|
||||
|
||||
目标:
|
||||
|
||||
- 将后端 `manifest_url` 适配为当前配置体系可消费的输入
|
||||
|
||||
验收标准:
|
||||
|
||||
- 同一个 Event 的线上发布内容可稳定映射为游戏配置入口
|
||||
|
||||
### 阶段四:session 下游联通
|
||||
|
||||
目标:
|
||||
|
||||
- 补充上报、完成、结果、历史查询
|
||||
|
||||
验收标准:
|
||||
|
||||
- 业务链路打通
|
||||
- 规则层仍不直接依赖业务 API
|
||||
|
||||
## 11. 必须长期坚持的规则
|
||||
|
||||
- 业务 API 不定义玩法
|
||||
- 配置文件不承载用户态
|
||||
- 引擎不依赖登录状态
|
||||
- 引擎不依赖报名状态
|
||||
- 业务页不直接修改 `GameDefinition`
|
||||
- 规则层不直接请求业务 API
|
||||
|
||||
如果后续出现需求需要绕过这几条规则,应视为架构变更,不应当作普通功能迭代处理。
|
||||
|
||||
## 12. 一句话总结
|
||||
|
||||
线上系统负责“把用户送进正确的一局游戏”,配置系统负责“定义这局游戏是什么”。
|
||||
Reference in New Issue
Block a user