新建项目
This commit is contained in:
229
docs/TECHNICAL_DESIGN.md
Normal file
229
docs/TECHNICAL_DESIGN.md
Normal file
@@ -0,0 +1,229 @@
|
||||
# 技术设计
|
||||
|
||||
## 1. 当前原型架构
|
||||
|
||||
当前版本采用微信小程序原生 JavaScript,不依赖 npm 包和远程服务。
|
||||
|
||||
```text
|
||||
页面层 pages/*
|
||||
↓
|
||||
本地游戏服务 services/game-service.js
|
||||
↓
|
||||
wx Storage(房间、玩家、事件和结果)
|
||||
```
|
||||
|
||||
`game-service.js` 将页面与数据源隔离。接入真实后端时,页面调用接口可以尽量保持不变,只需将服务实现替换为网络请求和实时订阅。
|
||||
|
||||
## 2. 推荐生产架构
|
||||
|
||||
初期建议采用微信云开发,减少登录、部署和运维成本;验证规模后可迁移为自有服务。
|
||||
|
||||
```text
|
||||
微信小程序
|
||||
├─ HTTPS API:创建、加入、抓捕、技能、结算
|
||||
├─ WebSocket:房间状态和事件推送
|
||||
└─ 定位模块:低频位置上报与边界判断
|
||||
↓
|
||||
应用服务
|
||||
├─ 身份与权限
|
||||
├─ 房间状态机
|
||||
├─ 游戏规则引擎
|
||||
├─ 位置模糊化
|
||||
├─ 口令与防作弊
|
||||
└─ 安全事件
|
||||
↓
|
||||
数据层
|
||||
├─ 持久数据库:用户、房间、结果
|
||||
├─ Redis:在线状态、口令、房间实时状态
|
||||
└─ 短期位置存储:设置自动过期时间
|
||||
```
|
||||
|
||||
## 3. 核心实体
|
||||
|
||||
### User
|
||||
|
||||
```js
|
||||
{
|
||||
id,
|
||||
openId,
|
||||
displayName,
|
||||
avatarUrl,
|
||||
safetySettings,
|
||||
createdAt
|
||||
}
|
||||
```
|
||||
|
||||
### Room
|
||||
|
||||
```js
|
||||
{
|
||||
id,
|
||||
code,
|
||||
hostId,
|
||||
name,
|
||||
mode,
|
||||
status,
|
||||
settings: {
|
||||
maxPlayers,
|
||||
durationMinutes,
|
||||
prepareMinutes,
|
||||
clueIntervalMinutes,
|
||||
seekerCount,
|
||||
radiusMeters,
|
||||
skillsEnabled
|
||||
},
|
||||
center,
|
||||
phaseEndsAt,
|
||||
version,
|
||||
createdAt
|
||||
}
|
||||
```
|
||||
|
||||
### Player
|
||||
|
||||
```js
|
||||
{
|
||||
id,
|
||||
roomId,
|
||||
userId,
|
||||
displayName,
|
||||
role,
|
||||
status,
|
||||
ready,
|
||||
caughtBy,
|
||||
caughtAt,
|
||||
joinedAt,
|
||||
lastSeenAt
|
||||
}
|
||||
```
|
||||
|
||||
### GameEvent
|
||||
|
||||
```js
|
||||
{
|
||||
id,
|
||||
roomId,
|
||||
type,
|
||||
actorId,
|
||||
targetId,
|
||||
visibility,
|
||||
payload,
|
||||
createdAt
|
||||
}
|
||||
```
|
||||
|
||||
### LocationPing
|
||||
|
||||
```js
|
||||
{
|
||||
roomId,
|
||||
playerId,
|
||||
latitude,
|
||||
longitude,
|
||||
accuracy,
|
||||
capturedAt,
|
||||
expiresAt
|
||||
}
|
||||
```
|
||||
|
||||
生产环境中 `LocationPing` 不应作为永久战绩保存。
|
||||
|
||||
## 4. API 草案
|
||||
|
||||
- `POST /rooms`:创建房间。
|
||||
- `GET /rooms/:code`:读取可公开的房间摘要。
|
||||
- `POST /rooms/:code/join`:加入房间。
|
||||
- `POST /rooms/:id/ready`:切换准备状态。
|
||||
- `POST /rooms/:id/start`:房主开始游戏。
|
||||
- `POST /rooms/:id/location`:上报位置。
|
||||
- `POST /rooms/:id/skills/:skill`:使用技能。
|
||||
- `POST /rooms/:id/captures`:提交抓捕凭证。
|
||||
- `POST /rooms/:id/pause`:暂停游戏。
|
||||
- `POST /rooms/:id/assemble`:发起全员集合。
|
||||
- `POST /rooms/:id/finish`:结束游戏。
|
||||
- `GET /rooms/:id/result`:读取结算结果。
|
||||
|
||||
所有改变游戏状态的接口都应:
|
||||
|
||||
- 校验用户身份和房间成员关系。
|
||||
- 校验当前房间状态和角色权限。
|
||||
- 使用服务端时间。
|
||||
- 支持幂等键,避免弱网重试造成重复事件。
|
||||
- 更新房间版本号并广播事件。
|
||||
|
||||
## 5. 实时同步
|
||||
|
||||
WebSocket 消息建议仅发送必要状态变化:
|
||||
|
||||
```js
|
||||
{
|
||||
eventId,
|
||||
roomId,
|
||||
roomVersion,
|
||||
type: "PLAYER_CAUGHT",
|
||||
payload: {},
|
||||
serverTime
|
||||
}
|
||||
```
|
||||
|
||||
客户端策略:
|
||||
|
||||
1. 进入候场或游戏页后建立连接。
|
||||
2. 按 `eventId` 去重。
|
||||
3. 检测版本跳跃时重新拉取房间快照。
|
||||
4. 退到后台后按微信能力选择保活或恢复时重连。
|
||||
5. UI 倒计时基于 `phaseEndsAt - serverTimeOffset` 计算。
|
||||
|
||||
## 6. 位置和地理围栏
|
||||
|
||||
- 客户端获取坐标并附带定位精度和采集时间。
|
||||
- 服务端校验坐标新鲜度、速度异常和精度阈值。
|
||||
- 使用服务端保存的场地中心和半径判断越界。
|
||||
- 向寻找者发送的线索由服务端完成网格化或随机偏移。
|
||||
- 不将躲藏者原始坐标发送给其他普通玩家。
|
||||
- 位置记录设置短期 TTL,游戏结束后触发删除任务。
|
||||
|
||||
线索模糊化可采用:
|
||||
|
||||
- H3/Geohash 网格降级。
|
||||
- 以真实点为中心生成受边界约束的随机圆。
|
||||
- 仅返回目标与玩家的距离档位,如“很近、附近、较远”。
|
||||
|
||||
## 7. 抓捕防作弊
|
||||
|
||||
动态口令建议由服务端生成:
|
||||
|
||||
```text
|
||||
token = HMAC(roomSecret, targetPlayerId + timeWindow + nonce)
|
||||
```
|
||||
|
||||
- 口令窗口建议 30 秒。
|
||||
- 提交时校验寻找者与目标的最近位置距离。
|
||||
- 校验双方都在线、角色正确且目标尚未被抓。
|
||||
- 使用事务写入抓捕结果,防止两个寻找者同时抓到同一目标。
|
||||
- 口令只作为相遇证明之一,不能替代安全规则。
|
||||
|
||||
## 8. 安全设计
|
||||
|
||||
- 房主开始前必须完成场地和规则确认。
|
||||
- 服务端保留暂停、集合和取消的高优先级事件通道。
|
||||
- 客户端进入后台、定位失效、低电量或离线时产生状态提示。
|
||||
- 精确位置访问纳入服务端审计,不允许普通运营后台随意查看。
|
||||
- 公开组局上线前必须具备举报、封禁、内容安全和年龄策略。
|
||||
|
||||
## 9. 测试策略
|
||||
|
||||
- 单元测试:房间状态机、身份分配、倒计时、抓捕和结算。
|
||||
- 属性测试:不同人数与寻找者数量下角色数量始终合法。
|
||||
- 集成测试:多人并发加入、重复抓捕、断线重连和版本冲突。
|
||||
- 真机测试:前后台切换、弱网、定位精度、耗电和不同微信版本。
|
||||
- 户外测试:边界提醒时机、线索节奏、屏幕使用时间和安全流程。
|
||||
|
||||
## 10. 迁移顺序
|
||||
|
||||
1. 保留页面与服务接口,先把本地房间读写替换为云函数。
|
||||
2. 接入微信登录并使每个玩家拥有稳定服务端 ID。
|
||||
3. 引入实时房间事件和服务端倒计时。
|
||||
4. 接入地图选区、定位上报和模糊线索。
|
||||
5. 将抓捕、技能和结算全部迁到服务端裁决。
|
||||
6. 增加日志、监控、隐私删除和运营安全能力。
|
||||
Reference in New Issue
Block a user