762 lines
16 KiB
Markdown
762 lines
16 KiB
Markdown
# 游戏配置全量模板(当前开发实现版)
|
||
|
||
本文档提供一份 **截至当前开发状态,客户端已实现或已正式消费的较完整配置模板**。
|
||
|
||
目标:
|
||
|
||
- 给后端、后台、联调一份“当前最全可用模板”
|
||
- 帮助梳理哪些字段已经生效
|
||
- 后续新增字段时,以这份模板持续补充
|
||
|
||
说明:
|
||
|
||
- 本模板优先以**当前客户端代码真实实现**为准
|
||
- 不是未来终态,只代表“当前这一版已经能消费的字段”
|
||
- 以顺序赛为主模板,同时说明积分赛差异点
|
||
|
||
---
|
||
|
||
## 1. 当前最全模板
|
||
|
||
```json
|
||
{
|
||
"schemaVersion": "1",
|
||
"version": "2026.03.30",
|
||
"app": {
|
||
"id": "sample-full-001",
|
||
"title": "完整配置示例",
|
||
"locale": "zh-CN"
|
||
},
|
||
"settings": {
|
||
"autoRotateEnabled": {
|
||
"value": true,
|
||
"isLocked": false
|
||
},
|
||
"trackDisplayMode": {
|
||
"value": "tail",
|
||
"isLocked": false
|
||
},
|
||
"gpsMarkerStyle": {
|
||
"value": "beacon",
|
||
"isLocked": true
|
||
},
|
||
"showCenterScaleRuler": {
|
||
"value": false,
|
||
"isLocked": false
|
||
}
|
||
},
|
||
"map": {
|
||
"tiles": "../map/lxcb-001/tiles/",
|
||
"mapmeta": "../map/lxcb-001/tiles/meta.json",
|
||
"declination": 6.91,
|
||
"initialView": {
|
||
"zoom": 17
|
||
}
|
||
},
|
||
"playfield": {
|
||
"kind": "course",
|
||
"source": {
|
||
"type": "kml",
|
||
"url": "../kml/lxcb-001/10/c01.kml"
|
||
},
|
||
"CPRadius": 6,
|
||
"controlDefaults": {
|
||
"score": 10,
|
||
"template": "story",
|
||
"autoPopup": false,
|
||
"pointStyle": "classic-ring",
|
||
"pointColorHex": "#cc006b"
|
||
},
|
||
"metadata": {
|
||
"title": "完整路线示例",
|
||
"code": "full-001"
|
||
},
|
||
"controlOverrides": {
|
||
"start-1": {
|
||
"template": "focus",
|
||
"title": "比赛开始",
|
||
"body": "从这里触发,先熟悉地图方向。",
|
||
"clickTitle": "起点说明",
|
||
"clickBody": "点击起点可再次查看起跑说明。",
|
||
"autoPopup": true,
|
||
"once": true,
|
||
"priority": 1,
|
||
"contentExperience": {
|
||
"type": "h5",
|
||
"url": "https://example.com/content/start-1",
|
||
"bridge": "content-v1",
|
||
"presentation": "fullscreen"
|
||
},
|
||
"clickExperience": {
|
||
"type": "h5",
|
||
"url": "https://example.com/content/start-1-click",
|
||
"bridge": "content-v1",
|
||
"presentation": "fullscreen"
|
||
}
|
||
},
|
||
"control-1": {
|
||
"template": "story",
|
||
"score": 10,
|
||
"title": "第一检查点",
|
||
"body": "完成该点后继续推进。",
|
||
"clickTitle": "第一检查点",
|
||
"clickBody": "点击查看该点的补充说明。",
|
||
"autoPopup": true,
|
||
"once": false,
|
||
"priority": 1,
|
||
"contentExperience": {
|
||
"type": "h5",
|
||
"url": "https://example.com/content/control-1",
|
||
"bridge": "content-v1",
|
||
"presentation": "fullscreen"
|
||
},
|
||
"clickExperience": {
|
||
"type": "h5",
|
||
"url": "https://example.com/content/control-1-click",
|
||
"bridge": "content-v1",
|
||
"presentation": "fullscreen"
|
||
}
|
||
},
|
||
"control-2": {
|
||
"template": "minimal",
|
||
"title": "第二检查点",
|
||
"body": "这个点配置成手动查看内容。",
|
||
"clickTitle": "第二检查点",
|
||
"clickBody": "点击查看手动内容。",
|
||
"autoPopup": false,
|
||
"once": true,
|
||
"priority": 1
|
||
},
|
||
"finish-1": {
|
||
"template": "focus",
|
||
"title": "比赛结束",
|
||
"body": "恭喜完成本次路线。",
|
||
"clickTitle": "终点说明",
|
||
"clickBody": "点击终点可再次查看结束说明。",
|
||
"autoPopup": false,
|
||
"once": true,
|
||
"priority": 2,
|
||
"clickExperience": {
|
||
"type": "h5",
|
||
"url": "https://example.com/content/finish-1-click",
|
||
"bridge": "content-v1",
|
||
"presentation": "fullscreen"
|
||
}
|
||
}
|
||
},
|
||
"legDefaults": {
|
||
"style": "classic-leg",
|
||
"colorHex": "#cc006b",
|
||
"widthScale": 1
|
||
}
|
||
},
|
||
"game": {
|
||
"mode": "classic-sequential",
|
||
"rulesVersion": "1",
|
||
"session": {
|
||
"startManually": false,
|
||
"requiresStartPunch": true,
|
||
"requiresFinishPunch": true,
|
||
"autoFinishOnLastControl": false,
|
||
"minCompletedControlsBeforeFinish": 1,
|
||
"maxDurationSec": 5400
|
||
},
|
||
"punch": {
|
||
"policy": "enter-confirm",
|
||
"radiusMeters": 5,
|
||
"requiresFocusSelection": false
|
||
},
|
||
"sequence": {
|
||
"skip": {
|
||
"enabled": true,
|
||
"radiusMeters": 10,
|
||
"requiresConfirm": false
|
||
}
|
||
},
|
||
"guidance": {
|
||
"showLegs": true,
|
||
"legAnimation": true,
|
||
"allowFocusSelection": false
|
||
},
|
||
"visibility": {
|
||
"revealFullPlayfieldAfterStartPunch": true
|
||
},
|
||
"finish": {
|
||
"finishControlAlwaysSelectable": false
|
||
},
|
||
"telemetry": {
|
||
"heartRate": {
|
||
"age": 30,
|
||
"restingHeartRateBpm": 62,
|
||
"userWeightKg": 65
|
||
}
|
||
},
|
||
"audio": {
|
||
"distantDistanceMeters": 80,
|
||
"approachDistanceMeters": 20,
|
||
"readyDistanceMeters": 5,
|
||
"cues": {
|
||
"guidance:distant": {
|
||
"loopGapMs": 4800,
|
||
"volume": 0.34
|
||
},
|
||
"guidance:approaching": {
|
||
"loopGapMs": 950,
|
||
"volume": 0.58
|
||
},
|
||
"guidance:ready": {
|
||
"loopGapMs": 650,
|
||
"volume": 0.68
|
||
}
|
||
}
|
||
},
|
||
"feedback": {
|
||
"audioProfile": "default",
|
||
"hapticsProfile": "default",
|
||
"uiEffectsProfile": "default"
|
||
}
|
||
},
|
||
"resources": {
|
||
"audioProfile": "default",
|
||
"contentProfile": "default",
|
||
"themeProfile": "default-race"
|
||
},
|
||
"debug": {
|
||
"allowModeSwitch": false,
|
||
"allowMockInput": false,
|
||
"allowSimulator": false
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 顶层字段说明
|
||
|
||
### `schemaVersion`
|
||
|
||
- 类型:`string`
|
||
- 必填:是
|
||
- 说明:配置结构版本
|
||
- 当前建议值:`"1"`
|
||
|
||
### `version`
|
||
|
||
- 类型:`string`
|
||
- 必填:是
|
||
- 说明:配置内容版本号
|
||
|
||
### `app`
|
||
|
||
- 类型:`object`
|
||
- 必填:是
|
||
- 说明:活动级基础信息
|
||
|
||
### `map`
|
||
|
||
- 类型:`object`
|
||
- 必填:是
|
||
- 说明:地图底座信息
|
||
|
||
### `playfield`
|
||
|
||
- 类型:`object`
|
||
- 必填:是
|
||
- 说明:点位空间、内容覆盖、点位元信息
|
||
|
||
### `game`
|
||
|
||
- 类型:`object`
|
||
- 必填:是
|
||
- 说明:玩法规则与对局流程
|
||
|
||
### `resources`
|
||
|
||
- 类型:`object`
|
||
- 必填:否
|
||
- 说明:资源 profile 引用
|
||
|
||
### `debug`
|
||
|
||
- 类型:`object`
|
||
- 必填:否
|
||
- 说明:调试开关
|
||
|
||
---
|
||
|
||
## 3. `app` 字段说明
|
||
|
||
### `app.id`
|
||
|
||
- 类型:`string`
|
||
- 说明:活动配置 ID
|
||
|
||
### `app.title`
|
||
|
||
- 类型:`string`
|
||
- 说明:活动标题 / 比赛名称
|
||
|
||
### `app.locale`
|
||
|
||
- 类型:`string`
|
||
- 说明:语言环境
|
||
- 当前常用值:`zh-CN`
|
||
|
||
---
|
||
|
||
## 4. `map` 字段说明
|
||
|
||
### `map.tiles`
|
||
|
||
- 类型:`string`
|
||
- 必填:是
|
||
- 说明:瓦片根路径
|
||
|
||
### `map.mapmeta`
|
||
|
||
- 类型:`string`
|
||
- 必填:是
|
||
- 说明:地图 meta 文件路径
|
||
|
||
### `map.declination`
|
||
|
||
- 类型:`number`
|
||
- 必填:否
|
||
- 说明:磁偏角
|
||
- 影响:真北 / 磁北换算
|
||
|
||
### `map.initialView.zoom`
|
||
|
||
- 类型:`number`
|
||
- 必填:否
|
||
- 说明:初始缩放级别
|
||
- 建议默认值:`17`
|
||
|
||
---
|
||
|
||
## 5. `playfield` 字段说明
|
||
|
||
### `playfield.kind`
|
||
|
||
- 类型:`string`
|
||
- 说明:空间对象类型
|
||
- 当前常用值:
|
||
- `course`
|
||
- `control-set`
|
||
|
||
### `playfield.source.type`
|
||
|
||
- 类型:`string`
|
||
- 说明:空间来源类型
|
||
- 当前推荐值:`kml`
|
||
|
||
### `playfield.source.url`
|
||
|
||
- 类型:`string`
|
||
- 说明:KML 路径
|
||
|
||
### `playfield.CPRadius`
|
||
|
||
- 类型:`number`
|
||
- 说明:检查点绘制半径
|
||
- 建议默认值:`6`
|
||
|
||
### `playfield.metadata.title`
|
||
|
||
- 类型:`string`
|
||
- 说明:路线标题
|
||
|
||
### `playfield.metadata.code`
|
||
|
||
- 类型:`string`
|
||
- 说明:路线编码
|
||
|
||
---
|
||
|
||
## 6. `playfield.controlDefaults` / `playfield.controlOverrides` 字段说明
|
||
|
||
推荐优先级:
|
||
|
||
`系统默认值 -> 玩法默认值 -> playfield.controlDefaults -> playfield.controlOverrides`
|
||
|
||
### `playfield.controlDefaults`
|
||
|
||
- 类型:`object`
|
||
- 说明:普通检查点的活动级默认配置
|
||
- 作用:减少重复书写,未单独覆盖的普通检查点默认继承这里
|
||
|
||
### `playfield.controlOverrides`
|
||
|
||
- 类型:`object`
|
||
- 说明:起点、普通点、终点的单点覆盖
|
||
- 作用:只写与活动默认不同的点
|
||
|
||
### key 命名规则
|
||
|
||
- 起点:`start-1`
|
||
- 普通点:`control-1`、`control-2`、`control-3`
|
||
- 终点:`finish-1`
|
||
|
||
### 当前支持字段
|
||
|
||
#### `template`
|
||
|
||
- 类型:`string`
|
||
- 说明:原生内容卡模板
|
||
- 当前支持:
|
||
- `minimal`
|
||
- `story`
|
||
- `focus`
|
||
|
||
#### `score`
|
||
|
||
- 类型:`number`
|
||
- 说明:积分赛点位分值
|
||
|
||
#### `title`
|
||
|
||
- 类型:`string`
|
||
- 说明:打点完成后自动弹出的标题
|
||
|
||
#### `body`
|
||
|
||
- 类型:`string`
|
||
- 说明:打点完成后自动弹出的正文
|
||
|
||
#### `clickTitle`
|
||
|
||
- 类型:`string`
|
||
- 说明:点击点位时弹出的标题
|
||
- 默认逻辑:最小模板下默认不启用;仅在显式配置点击内容能力时生效
|
||
|
||
#### `clickBody`
|
||
|
||
- 类型:`string`
|
||
- 说明:点击点位时弹出的正文
|
||
- 默认逻辑:最小模板下默认不启用;仅在显式配置点击内容能力时生效
|
||
|
||
#### `autoPopup`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:打点完成后是否自动弹出
|
||
- 默认逻辑:最小模板下默认 `false`
|
||
- 特殊逻辑:`game.punch.policy = "enter"` 时不自动弹原生内容
|
||
- 补充说明:白色内容卡已改为显式配置启用;普通点只有显式设置 `autoPopup = true` 才会在打点后先弹白卡
|
||
- 补充说明:终点完成后默认直接进入结果页,不走白色内容卡链路
|
||
|
||
#### `once`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:本局只展示一次
|
||
- 默认逻辑:`false`
|
||
|
||
#### `priority`
|
||
|
||
- 类型:`number`
|
||
- 说明:内容优先级,越大越高
|
||
- 默认逻辑:
|
||
- 普通点:`1`
|
||
- 终点:`2`
|
||
|
||
#### `contentExperience`
|
||
|
||
- 类型:`object`
|
||
- 说明:打点完成后的 H5 详情/互动扩展配置
|
||
- 注意:当前不是直接顶替原生弹窗,而是通过原生卡片 CTA 进入
|
||
|
||
#### `contentExperience.type`
|
||
|
||
- 类型:`string`
|
||
- 说明:内容扩展承载类型
|
||
- 当前支持:
|
||
- `native`
|
||
- `h5`
|
||
|
||
#### `contentExperience.url`
|
||
|
||
- 类型:`string`
|
||
- 说明:H5 详情页地址
|
||
|
||
#### `contentExperience.bridge`
|
||
|
||
- 类型:`string`
|
||
- 说明:Bridge 协议版本
|
||
- 当前推荐值:`content-v1`
|
||
|
||
#### `contentExperience.presentation`
|
||
|
||
- 类型:`string`
|
||
- 说明:H5 内容页展示形态
|
||
- 当前运行建议:
|
||
- `fullscreen`
|
||
- 兼容历史值:
|
||
- `dialog`
|
||
- `sheet`
|
||
- 备注:经过真机验证,`web-view` 不再承担局部弹窗职责;当前应按“原生内容卡 + H5 全屏详情页/任务页”理解。
|
||
|
||
#### `clickExperience`
|
||
|
||
- 类型:`object`
|
||
- 说明:点击点位时的 H5 详情/互动扩展配置
|
||
- 规则同 `contentExperience`
|
||
|
||
---
|
||
|
||
## 7. `game` 字段说明
|
||
|
||
### `game.mode`
|
||
|
||
- 类型:`string`
|
||
- 说明:玩法模式
|
||
- 当前常用值:
|
||
- `classic-sequential`
|
||
- `score-o`
|
||
|
||
### `game.rulesVersion`
|
||
|
||
- 类型:`string`
|
||
- 说明:规则版本号
|
||
|
||
### `game.session.startManually`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:是否手动开始
|
||
- 顺序赛建议默认值:`false`
|
||
|
||
### `game.session.requiresStartPunch`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:是否必须打起点
|
||
|
||
### `game.session.requiresFinishPunch`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:是否必须打终点
|
||
|
||
### `game.session.autoFinishOnLastControl`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:最后一个目标完成后是否自动结束
|
||
|
||
### `game.session.minCompletedControlsBeforeFinish`
|
||
|
||
- 类型:`number`
|
||
- 说明:终点生效前至少需要完成的普通检查点数量
|
||
- 建议默认值:
|
||
- 顺序赛:`0`
|
||
- 积分赛:`1`
|
||
|
||
### `game.session.maxDurationSec`
|
||
|
||
- 类型:`number`
|
||
- 说明:最大对局时长,单位秒
|
||
|
||
### `game.punch.policy`
|
||
|
||
- 类型:`string`
|
||
- 说明:打点策略
|
||
- 当前常用值:
|
||
- `enter-confirm`
|
||
- `enter`
|
||
|
||
### `game.punch.radiusMeters`
|
||
|
||
- 类型:`number`
|
||
- 说明:打点半径,单位米
|
||
|
||
### `game.punch.requiresFocusSelection`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:是否需要先聚焦/选中目标再打点
|
||
- 建议默认值:
|
||
- 顺序赛:`false`
|
||
- 积分赛:`false`
|
||
|
||
### `game.sequence.skip.enabled`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:顺序赛是否允许跳点
|
||
|
||
### `game.sequence.skip.radiusMeters`
|
||
|
||
- 类型:`number`
|
||
- 说明:跳点可用半径
|
||
- 顺序赛建议默认值:打点半径的 `2` 倍
|
||
|
||
### `game.sequence.skip.requiresConfirm`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:跳点是否需要二次确认
|
||
- 顺序赛建议默认值:`false`
|
||
|
||
### `game.guidance.showLegs`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:是否显示路线腿段
|
||
|
||
### `game.guidance.legAnimation`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:是否开启路线腿段动画
|
||
|
||
### `game.guidance.allowFocusSelection`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:是否允许点击点位选中目标
|
||
|
||
### `game.visibility.revealFullPlayfieldAfterStartPunch`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:打完起点后是否显示完整场地
|
||
|
||
### `game.finish.finishControlAlwaysSelectable`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:终点是否始终可选
|
||
|
||
### `game.telemetry.heartRate.age`
|
||
|
||
- 类型:`number`
|
||
- 说明:用户年龄
|
||
|
||
### `game.telemetry.heartRate.restingHeartRateBpm`
|
||
|
||
- 类型:`number`
|
||
- 说明:静息心率
|
||
|
||
### `game.telemetry.heartRate.userWeightKg`
|
||
|
||
- 类型:`number`
|
||
- 说明:体重,单位公斤
|
||
|
||
### `game.feedback.audioProfile`
|
||
|
||
- 类型:`string`
|
||
- 说明:音效 profile
|
||
|
||
### `game.feedback.hapticsProfile`
|
||
|
||
- 类型:`string`
|
||
- 说明:震动 profile
|
||
|
||
### `game.feedback.uiEffectsProfile`
|
||
|
||
- 类型:`string`
|
||
- 说明:UI 动效 profile
|
||
|
||
### `game.audio`
|
||
|
||
- 类型:`object`
|
||
- 说明:高级音频运行时配置,用于控制三档距离提示音的距离阈值和 cue 参数
|
||
|
||
### `game.audio.distantDistanceMeters`
|
||
|
||
- 类型:`number`
|
||
- 说明:远距离提示音阈值
|
||
- 建议默认值:`80`
|
||
|
||
### `game.audio.approachDistanceMeters`
|
||
|
||
- 类型:`number`
|
||
- 说明:接近提示音阈值
|
||
- 建议默认值:`20`
|
||
|
||
### `game.audio.readyDistanceMeters`
|
||
|
||
- 类型:`number`
|
||
- 说明:可打点提示音阈值
|
||
- 建议默认值:`5`
|
||
- 备注:
|
||
- 运行时不会低于 `game.punch.radiusMeters`
|
||
|
||
### `game.audio.cues["guidance:distant" | "guidance:approaching" | "guidance:ready"]`
|
||
|
||
- 类型:`object`
|
||
- 说明:三档距离提示音的 cue 级配置
|
||
- 当前支持字段:
|
||
- `src`
|
||
- `volume`
|
||
- `loop`
|
||
- `loopGapMs`
|
||
|
||
---
|
||
|
||
## 8. `resources` 字段说明
|
||
|
||
### `resources.audioProfile`
|
||
|
||
- 类型:`string`
|
||
- 说明:资源音效配置档
|
||
|
||
### `resources.contentProfile`
|
||
|
||
- 类型:`string`
|
||
- 说明:内容资源配置档
|
||
|
||
### `resources.themeProfile`
|
||
|
||
- 类型:`string`
|
||
- 说明:主题配置档
|
||
|
||
---
|
||
|
||
## 9. `debug` 字段说明
|
||
|
||
### `debug.allowModeSwitch`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:是否允许玩法切换调试
|
||
|
||
### `debug.allowMockInput`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:是否允许模拟输入
|
||
|
||
### `debug.allowSimulator`
|
||
|
||
- 类型:`boolean`
|
||
- 说明:是否允许模拟器调试
|
||
|
||
---
|
||
|
||
## 10. 积分赛差异点
|
||
|
||
如果使用积分赛,通常要修改这几项:
|
||
|
||
```json
|
||
{
|
||
"playfield": {
|
||
"kind": "control-set"
|
||
},
|
||
"game": {
|
||
"mode": "score-o",
|
||
"session": {
|
||
"startManually": false
|
||
},
|
||
"punch": {
|
||
"requiresFocusSelection": true
|
||
},
|
||
"guidance": {
|
||
"showLegs": false,
|
||
"legAnimation": false,
|
||
"allowFocusSelection": true
|
||
},
|
||
"finish": {
|
||
"finishControlAlwaysSelectable": true
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
并在 `playfield.controlDefaults` 中先写普通点统一默认,必要时再在 `playfield.controlOverrides` 中为少量特殊点补:
|
||
|
||
- `score`
|
||
|
||
---
|
||
|
||
## 11. 推荐配套阅读
|
||
|
||
- [D:\dev\cmr-mini\doc\config-template-minimal-game.md](D:/dev/cmr-mini/doc/config/最小游戏配置模板.md)
|
||
- [D:\dev\cmr-mini\doc\config-option-dictionary.md](D:/dev/cmr-mini/doc/config/配置选项字典.md)
|
||
- [D:\dev\cmr-mini\doc\config-docs-index.md](D:/dev/cmr-mini/doc/config/配置文档索引.md)
|