357 lines
6.6 KiB
Markdown
357 lines
6.6 KiB
Markdown
# 积分赛配置文档(基础版)
|
|
|
|
本文档用于给服务端和后台配置设计提供一份可直接落地的积分赛基础模板。
|
|
目标是先把积分赛入口结构定稳,后续程序功能再逐步细化。
|
|
|
|
---
|
|
|
|
## 1. 适用玩法
|
|
|
|
适用于最基础的积分赛玩法:
|
|
|
|
- 手动开始
|
|
- 先打开始点
|
|
- 多个检查点自由收集
|
|
- 控制点有固定分值
|
|
- 可选终点
|
|
- 支持选中目标点后打卡
|
|
|
|
---
|
|
|
|
## 2. 顶层结构
|
|
|
|
推荐主配置结构如下:
|
|
|
|
```json
|
|
{
|
|
"schemaVersion": "1",
|
|
"version": "2026.03.25",
|
|
"app": {},
|
|
"map": {},
|
|
"playfield": {},
|
|
"game": {},
|
|
"resources": {},
|
|
"debug": {}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 3. 完整示例
|
|
|
|
```json
|
|
{
|
|
"schemaVersion": "1",
|
|
"version": "2026.03.25",
|
|
"app": {
|
|
"id": "lxcb-001",
|
|
"title": "雪熊领秀城区积分赛",
|
|
"locale": "zh-CN"
|
|
},
|
|
"map": {
|
|
"tiles": "lxcb-001/tiles/",
|
|
"mapmeta": "lxcb-001/tiles/meta.json",
|
|
"declination": 6.91,
|
|
"initialView": {
|
|
"zoom": 17
|
|
}
|
|
},
|
|
"playfield": {
|
|
"kind": "control-set",
|
|
"source": {
|
|
"type": "kml",
|
|
"url": "lxcb-001/course/c01.kml"
|
|
},
|
|
"CPRadius": 6,
|
|
"controlOverrides": {
|
|
"control-1": {
|
|
"score": 10
|
|
},
|
|
"control-2": {
|
|
"score": 20
|
|
},
|
|
"control-3": {
|
|
"score": 30
|
|
},
|
|
"control-4": {
|
|
"score": 40
|
|
}
|
|
},
|
|
"metadata": {
|
|
"title": "校园积分赛控制点集",
|
|
"code": "score-o-c01"
|
|
}
|
|
},
|
|
"game": {
|
|
"mode": "score-o",
|
|
"rulesVersion": "1",
|
|
"session": {
|
|
"startManually": true,
|
|
"requiresStartPunch": true,
|
|
"requiresFinishPunch": false,
|
|
"autoFinishOnLastControl": false,
|
|
"maxDurationSec": 5400
|
|
},
|
|
"punch": {
|
|
"policy": "enter-confirm",
|
|
"radiusMeters": 10,
|
|
"requiresFocusSelection": true
|
|
},
|
|
"scoring": {
|
|
"type": "score",
|
|
"defaultControlScore": 10
|
|
},
|
|
"guidance": {
|
|
"showLegs": false,
|
|
"legAnimation": false,
|
|
"allowFocusSelection": true
|
|
},
|
|
"visibility": {
|
|
"revealFullPlayfieldAfterStartPunch": true
|
|
},
|
|
"finish": {
|
|
"finishControlAlwaysSelectable": true
|
|
},
|
|
"telemetry": {
|
|
"heartRate": {
|
|
"age": 30,
|
|
"restingHeartRateBpm": 62,
|
|
"userWeightKg": 65
|
|
}
|
|
},
|
|
"feedback": {
|
|
"audioProfile": "default",
|
|
"hapticsProfile": "default",
|
|
"uiEffectsProfile": "default"
|
|
}
|
|
},
|
|
"resources": {
|
|
"audioProfile": "default",
|
|
"contentProfile": "default",
|
|
"themeProfile": "default-race"
|
|
},
|
|
"debug": {
|
|
"allowModeSwitch": false,
|
|
"allowMockInput": false,
|
|
"allowSimulator": false
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 4. 字段说明
|
|
|
|
### `app`
|
|
|
|
- `id`
|
|
活动或配置实例 id
|
|
- `title`
|
|
活动标题
|
|
- `locale`
|
|
语言环境
|
|
|
|
### `map`
|
|
|
|
- `tiles`
|
|
瓦片根路径
|
|
- `mapmeta`
|
|
地图 meta 地址
|
|
- `declination`
|
|
磁偏角
|
|
- `initialView.zoom`
|
|
初始缩放级别
|
|
|
|
### `playfield`
|
|
|
|
- `kind`
|
|
当前推荐 `control-set`
|
|
- `source.type`
|
|
当前推荐 `kml`
|
|
- `source.url`
|
|
KML 地址
|
|
- `CPRadius`
|
|
检查点绘制半径
|
|
- `controlOverrides`
|
|
每个控制点的积分和后续扩展元数据
|
|
|
|
### `playfield.controlOverrides`
|
|
|
|
当前阶段最推荐至少放:
|
|
|
|
- `score`
|
|
|
|
示例:
|
|
|
|
```json
|
|
"control-1": {
|
|
"score": 10
|
|
}
|
|
```
|
|
|
|
这样可以保证:
|
|
|
|
- KML 只提供点位与空间结构
|
|
- 分值由配置控制
|
|
|
|
### `game.session`
|
|
|
|
- `startManually`
|
|
是否手动开始
|
|
- `requiresStartPunch`
|
|
是否必须先打开始点
|
|
- `requiresFinishPunch`
|
|
是否必须打终点
|
|
- `autoFinishOnLastControl`
|
|
积分赛通常为 `false`
|
|
- `maxDurationSec`
|
|
最大时长
|
|
|
|
### `game.punch`
|
|
|
|
- `policy`
|
|
当前推荐 `enter-confirm`
|
|
- `radiusMeters`
|
|
打点半径
|
|
- `requiresFocusSelection`
|
|
是否必须先选中目标点后才能打卡
|
|
|
|
### `game.scoring`
|
|
|
|
- `type`
|
|
当前推荐 `score`
|
|
- `defaultControlScore`
|
|
如果某个点没单独配置分数时的默认值
|
|
|
|
### `game.guidance`
|
|
|
|
- `showLegs`
|
|
积分赛基础版建议 `false`
|
|
- `legAnimation`
|
|
积分赛基础版建议 `false`
|
|
- `allowFocusSelection`
|
|
建议 `true`
|
|
|
|
### `game.visibility`
|
|
|
|
- `revealFullPlayfieldAfterStartPunch`
|
|
开始点打卡后是否显示完整控制点集合
|
|
|
|
### `game.finish`
|
|
|
|
- `finishControlAlwaysSelectable`
|
|
积分赛建议支持随时选终点结束时,设为 `true`
|
|
|
|
### `game.telemetry`
|
|
|
|
通用体能参数。
|
|
|
|
### `game.feedback`
|
|
|
|
反馈 profile 绑定。
|
|
|
|
### `resources`
|
|
|
|
资源 profile 绑定。
|
|
|
|
### `debug`
|
|
|
|
调试相关开关。
|
|
|
|
---
|
|
|
|
## 5. 当前阶段推荐必填字段
|
|
|
|
积分赛当前阶段建议至少保证以下字段存在:
|
|
|
|
- `map.tiles`
|
|
- `map.mapmeta`
|
|
- `map.declination`
|
|
- `playfield.kind`
|
|
- `playfield.source.type`
|
|
- `playfield.source.url`
|
|
- `playfield.CPRadius`
|
|
- `game.mode`
|
|
- `game.punch.policy`
|
|
- `game.punch.radiusMeters`
|
|
- `game.punch.requiresFocusSelection`
|
|
- `game.scoring.type`
|
|
|
|
---
|
|
|
|
## 6. 当前阶段建议默认值
|
|
|
|
如果服务端还没有全部细项,建议先采用以下默认值:
|
|
|
|
```json
|
|
{
|
|
"game": {
|
|
"session": {
|
|
"startManually": true,
|
|
"requiresStartPunch": true,
|
|
"requiresFinishPunch": false,
|
|
"autoFinishOnLastControl": false
|
|
},
|
|
"punch": {
|
|
"policy": "enter-confirm",
|
|
"radiusMeters": 10,
|
|
"requiresFocusSelection": true
|
|
},
|
|
"scoring": {
|
|
"type": "score",
|
|
"defaultControlScore": 10
|
|
},
|
|
"guidance": {
|
|
"showLegs": false,
|
|
"legAnimation": false,
|
|
"allowFocusSelection": true
|
|
},
|
|
"finish": {
|
|
"finishControlAlwaysSelectable": true
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 7. 积分赛当前阶段推荐的设计边界
|
|
|
|
当前阶段建议坚持以下边界:
|
|
|
|
- KML 提供点位和几何底稿
|
|
- 配置提供分值和玩法解释
|
|
- 不把积分逻辑写进 KML
|
|
- 不把自由收集逻辑写成固定路线逻辑
|
|
|
|
也就是说:
|
|
|
|
- `playfield.kind = control-set`
|
|
- `controlOverrides.score` 负责分值
|
|
- `game.guidance.allowFocusSelection = true` 负责选中目标逻辑
|
|
|
|
---
|
|
|
|
## 8. 适合当前客户端的迁移原则
|
|
|
|
当前客户端迁移时,建议服务端先完成:
|
|
|
|
1. 将积分赛点位分值迁入 `playfield.controlOverrides`
|
|
2. 将玩法规则迁入 `game.session / game.punch / game.scoring / game.guidance / game.finish`
|
|
3. 不急着一次性接入动态积分和复杂规则
|
|
|
|
先把静态积分赛入口结构定稳,再逐步扩展动态积分和高级玩法能力。
|
|
|
|
---
|
|
|
|
## 9. 一句话结论
|
|
|
|
积分赛配置当前阶段建议:
|
|
|
|
- 用 `playfield.kind = control-set`
|
|
- 用 KML 承载控制点空间底稿
|
|
- 用 `playfield.controlOverrides` 承载点位分值
|
|
- 用 `game.scoring / game.punch / game.guidance / game.finish` 承载玩法规则
|
|
- 先把静态积分赛入口结构定稳,后续再扩动态积分与更复杂玩法
|
|
|