完善样式系统与调试链路底座

This commit is contained in:
2026-03-30 18:19:05 +08:00
parent 2c0fd4c549
commit 3b9117427e
40 changed files with 7526 additions and 389 deletions

View File

@@ -46,6 +46,30 @@
- 想知道字段应该怎么写
- 想确认默认行为时
### [track-visualization-proposal.md](D:/dev/cmr-mini/doc/track-visualization-proposal.md)
作用:
- 说明 `none / full / tail` 三种轨迹模式
- 说明拖尾轨迹的默认策略与推荐参数
- 说明当前轨迹样式的配置结构
### [gps-marker-style-system-proposal.md](D:/dev/cmr-mini/doc/gps-marker-style-system-proposal.md)
作用:
- 说明 GPS 点样式系统的目标分层
- 说明默认样式、朝向小三角和品牌 logo 扩展思路
- 说明第一阶段最小实现字段和长期演进方向
### [gps-marker-animation-system-proposal.md](D:/dev/cmr-mini/doc/gps-marker-animation-system-proposal.md)
作用:
- 说明 GPS 点动画系统的状态分层
- 说明 `idle / moving / fast-moving / warning` 的第一阶段实现思路
- 说明动画 profile、运行时内部字段和 `standard / lite` 降级策略
---
## 3. 默认配置模板
@@ -64,6 +88,36 @@
- 想直接照着填配置
- 想知道最小可运行模板长什么样
### [config-template-minimal-game.md](D:/dev/cmr-mini/doc/config-template-minimal-game.md)
作用:
- 提供“最小可跑”的游戏配置模板
- 去掉绝大部分选配项
- 适合快速起步、联调和排查配置链
### [config-template-minimal-classic-sequential.md](D:/dev/cmr-mini/doc/config-template-minimal-classic-sequential.md)
作用:
- 提供顺序赛最小可跑模板
- 适合快速起顺序赛活动
### [config-template-minimal-score-o.md](D:/dev/cmr-mini/doc/config-template-minimal-score-o.md)
作用:
- 提供积分赛最小可跑模板
- 适合快速起积分赛活动
### [config-template-full-current.md](D:/dev/cmr-mini/doc/config-template-full-current.md)
作用:
- 提供“当前开发状态最全”的配置模板
- 汇总目前客户端已实现或已消费的主要字段
- 适合后端、后台和联调统一对齐
---
## 4. 按玩法拆分的配置模板文档
@@ -137,10 +191,13 @@
1. [config-design-proposal.md](D:/dev/cmr-mini/doc/config-design-proposal.md)
2. [config-option-dictionary.md](D:/dev/cmr-mini/doc/config-option-dictionary.md)
3. [config-default-template.md](D:/dev/cmr-mini/doc/config-default-template.md)
4. [event/classic-sequential.json](D:/dev/cmr-mini/event/classic-sequential.json)
5. [event/score-o.json](D:/dev/cmr-mini/event/score-o.json)
6. [backend-config-management-v2.md](D:/dev/cmr-mini/doc/backend-config-management-v2.md)
3. [config-template-minimal-game.md](D:/dev/cmr-mini/doc/config-template-minimal-game.md)
4. [config-template-minimal-classic-sequential.md](D:/dev/cmr-mini/doc/config-template-minimal-classic-sequential.md)
5. [config-template-minimal-score-o.md](D:/dev/cmr-mini/doc/config-template-minimal-score-o.md)
6. [config-template-full-current.md](D:/dev/cmr-mini/doc/config-template-full-current.md)
7. [event/classic-sequential.json](D:/dev/cmr-mini/event/classic-sequential.json)
8. [event/score-o.json](D:/dev/cmr-mini/event/score-o.json)
9. [backend-config-management-v2.md](D:/dev/cmr-mini/doc/backend-config-management-v2.md)
---
@@ -149,9 +206,12 @@
后续每次新增配置能力时,建议至少同步更新这几处:
1. [config-option-dictionary.md](D:/dev/cmr-mini/doc/config-option-dictionary.md)
2. [config-default-template.md](D:/dev/cmr-mini/doc/config-default-template.md)
3. 对应玩法的 `event/*.json` 样例
4. 如果涉及顶层结构变化,再更新 [config-design-proposal.md](D:/dev/cmr-mini/doc/config-design-proposal.md)
2. [config-template-minimal-game.md](D:/dev/cmr-mini/doc/config-template-minimal-game.md)
3. [config-template-minimal-classic-sequential.md](D:/dev/cmr-mini/doc/config-template-minimal-classic-sequential.md)
4. [config-template-minimal-score-o.md](D:/dev/cmr-mini/doc/config-template-minimal-score-o.md)
5. [config-template-full-current.md](D:/dev/cmr-mini/doc/config-template-full-current.md)
6. 对应玩法的 `event/*.json` 样例
7. 如果涉及顶层结构变化,再更新 [config-design-proposal.md](D:/dev/cmr-mini/doc/config-design-proposal.md)
这样可以保证:

View File

@@ -313,6 +313,61 @@
- 类型:`string`
- 说明:点击内容的展示形态
#### `pointStyle`
- 类型:`string`
- 说明:单个控制点的样式覆盖,仅影响当前控制点
- 支持值:
- `classic-ring`
- `solid-dot`
- `double-ring`
- `badge`
- `pulse-core`
#### `pointColorHex`
- 类型:`string`
- 说明:单个控制点的颜色覆盖,例如 `#27ae60`
- 备注:通常和 `pointStyle` 一起使用,未配置时回退到玩法样式 profile
#### `pointSizeScale`
- 类型:`number`
- 说明:单个控制点的尺寸倍率覆盖
- 建议范围:`0.6 ~ 1.4`
- 建议默认值:`1`
- 备注:大于 `1` 会放大点位,小于 `1` 会缩小点位
#### `pointAccentRingScale`
- 类型:`number`
- 说明:单个控制点强调环/外环的尺寸倍率
- 建议范围:`1.0 ~ 1.6`
- 建议默认值:由样式 profile 决定
- 备注:适合当前点、高分点、终点这类需要更强层次感的点位
#### `pointGlowStrength`
- 类型:`number`
- 说明:单个控制点的光晕强度
- 建议范围:`0 ~ 1`
- 建议默认值:`0`
- 备注:`0` 为无光晕,越接近 `1` 光晕越明显
#### `pointLabelScale`
- 类型:`number`
- 说明:单个控制点编号文字的尺寸倍率
- 建议范围:`0.7 ~ 1.3`
- 建议默认值:`1`
- 备注:适合高价值点、终点、特殊活动点的编号强调
#### `pointLabelColorHex`
- 类型:`string`
- 说明:单个控制点编号文字颜色覆盖,例如 `#ffffff`
- 备注:未配置时回退到样式系统默认标签颜色逻辑
- 当前支持:
- `sheet`
- `dialog`
@@ -626,7 +681,369 @@
---
## 19. 当前默认逻辑说明
## 19. `game.presentation`
### `game.presentation.sequential.controls.default`
- 类型:`object`
- 说明:顺序赛普通未完成控制点的默认样式
- 支持字段:
- `style``classic-ring | solid-dot | double-ring | badge | pulse-core`
- `colorHex`:十六进制颜色,例如 `#cc006b`
- `sizeScale`:点位尺寸倍率
- `accentRingScale`:强调环尺寸倍率
- `glowStrength`:点位光晕强度
- `labelScale`:编号文字尺寸倍率
- `labelColorHex`:编号文字颜色
### `game.presentation.sequential.controls.current`
- 类型:`object`
- 说明:顺序赛当前目标点/可打点状态样式
### `game.presentation.sequential.controls.completed`
- 类型:`object`
- 说明:顺序赛已完成点样式
### `game.presentation.sequential.controls.skipped`
- 类型:`object`
- 说明:顺序赛已跳过点样式
### `game.presentation.sequential.controls.start`
- 类型:`object`
- 说明:顺序赛起点样式
### `game.presentation.sequential.controls.finish`
- 类型:`object`
- 说明:顺序赛终点样式
### `game.presentation.sequential.legs.default`
- 类型:`object`
- 说明:顺序赛默认路线腿样式
- 支持字段:
- `style``classic-leg | dashed-leg | glow-leg | progress-leg`
- `colorHex`:十六进制颜色
- `widthScale`:路线腿宽度倍率
- `glowStrength`:路线腿光晕强度
### `game.presentation.sequential.legs.completed`
- 类型:`object`
- 说明:顺序赛已完成路线腿样式
### `playfield.legOverrides`
- 类型:`object`
- 说明:对指定路线腿做局部样式覆盖
- 键名建议:
- `leg-1`
- `leg-2`
- `leg-3`
- 字段:
- `style``classic-leg | dashed-leg | glow-leg | progress-leg`
- `colorHex`:十六进制颜色
- `widthScale`:路线腿宽度倍率
- `glowStrength`:路线腿光晕强度
- 示例:
```json
"legOverrides": {
"leg-2": {
"style": "glow-leg",
"colorHex": "#27ae60"
}
}
```
### `game.presentation.scoreO.controls.default`
- 类型:`object`
- 说明:积分赛默认点位样式
### `game.presentation.scoreO.controls.focused`
- 类型:`object`
- 说明:积分赛当前聚焦/选中点样式
### `game.presentation.scoreO.controls.collected`
- 类型:`object`
- 说明:积分赛已收集点样式
### `game.presentation.scoreO.controls.start`
- 类型:`object`
- 说明:积分赛起点样式
### `game.presentation.scoreO.controls.finish`
- 类型:`object`
- 说明:积分赛终点样式
### `game.presentation.scoreO.controls.scoreBands`
- 类型:`array`
- 说明:积分赛按分值档位映射点位颜色和样式
- 数组项字段:
- `min`:分值下界,含
- `max`:分值上界,含
- `style``classic-ring | solid-dot | double-ring | badge | pulse-core`
- `colorHex`:十六进制颜色
- `sizeScale`:该积分档位的点位尺寸倍率
- `accentRingScale`:该积分档位的强调环倍率
- `glowStrength`:该积分档位的光晕强度
- `labelScale`:该积分档位的编号文字尺寸倍率
- `labelColorHex`:该积分档位的编号文字颜色
- 示例:
```json
"presentation": {
"scoreO": {
"controls": {
"scoreBands": [
{ "min": 0, "max": 19, "style": "classic-ring", "colorHex": "#56ccf2" },
{ "min": 20, "max": 49, "style": "double-ring", "colorHex": "#f2c94c" },
{ "min": 50, "max": 999999, "style": "badge", "colorHex": "#eb5757" }
]
}
}
}
```
---
## 20. `game.presentation.track`
- 类型:`object`
- 说明:用户轨迹显示策略与样式配置
### `game.presentation.track.mode`
- 类型:`string`
- 说明:轨迹显示模式
- 当前支持:
- `none`:不显示轨迹
- `tail`:彗尾拖尾
- `full`:全轨迹
- 建议默认值:
- 顺序赛:`full`
- 积分赛:`tail`
### `game.presentation.track.style`
- 类型:`string`
- 说明:轨迹风格 profile
- 当前支持:
- `classic`
- `neon`
- 当前默认值:`neon`
### `game.presentation.track.tailLength`
- 类型:`string`
- 说明:拖尾基础长度档位
- 当前支持:
- `short`
- `medium`
- `long`
- 备注:
- 实际显示长度会继续按移动速度动态变化
- 跑得越快,尾巴越长
- 跑得越慢,尾巴越短
### `game.presentation.track.colorPreset`
- 类型:`string`
- 说明:轨迹亮色调色盘
- 当前支持:
- `mint`
- `cyan`
- `sky`
- `blue`
- `violet`
- `pink`
- `orange`
- `yellow`
- 备注:
- 运行时会在此基础上根据速度和心率张力自动提亮头部颜色与光晕
### `game.presentation.track.tailMeters`
- 类型:`number`
- 说明:拖尾基础长度(米)
- 备注:
- 若未显式配置,则按 `tailLength` 自动映射
### `game.presentation.track.tailMaxSeconds`
- 类型:`number`
- 说明:拖尾最大时间窗口(秒)
### `game.presentation.track.fadeOutWhenStill`
- 类型:`boolean`
- 说明:静止后是否逐步收尾消失
### `game.presentation.track.stillSpeedKmh`
- 类型:`number`
- 说明:低于该速度时进入静止收尾逻辑
### `game.presentation.track.fadeOutDurationMs`
- 类型:`number`
- 说明:静止后拖尾完全淡出的时长(毫秒)
### `game.presentation.track.colorHex`
- 类型:`string`
- 说明:轨迹主色
- 备注:
- 未配置时按 `colorPreset` 自动映射
### `game.presentation.track.headColorHex`
- 类型:`string`
- 说明:轨迹头部高亮颜色
- 备注:
- 未配置时按 `colorPreset` 自动映射
### `game.presentation.track.widthPx`
- 类型:`number`
- 说明:轨迹基础宽度
### `game.presentation.track.headWidthPx`
- 类型:`number`
- 说明:轨迹头部高亮宽度
### `game.presentation.track.glowStrength`
- 类型:`number`
- 说明:轨迹光晕强度
- 备注:
- `standard / lite` 会自动做 glow 强度降级
---
## 21. `game.presentation.gpsMarker`
- 类型:`object`
- 说明GPS 定位点显示、尺寸、颜色、朝向指示和品牌化扩展配置
### `game.presentation.gpsMarker.visible`
- 类型:`boolean`
- 说明:是否显示 GPS 定位点
- 当前默认值:`true`
### `game.presentation.gpsMarker.style`
- 类型:`string`
- 说明GPS 点基础样式
- 当前支持:
- `dot`
- `beacon`
- `disc`
- `badge`
- 当前默认值:`beacon`
### `game.presentation.gpsMarker.size`
- 类型:`string`
- 说明GPS 点整体大小档位
- 当前支持:
- `small`
- `medium`
- `large`
- 当前默认值:`medium`
### `game.presentation.gpsMarker.colorPreset`
- 类型:`string`
- 说明GPS 点亮色调色盘
- 当前支持:
- `mint`
- `cyan`
- `sky`
- `blue`
- `violet`
- `pink`
- `orange`
- `yellow`
- 当前默认值:`cyan`
### `game.presentation.gpsMarker.colorHex`
- 类型:`string`
- 说明GPS 点主色
- 备注:
- 未配置时按 `colorPreset` 自动映射
### `game.presentation.gpsMarker.ringColorHex`
- 类型:`string`
- 说明GPS 点外圈颜色
- 备注:
- 未配置时按 `colorPreset` 自动映射
### `game.presentation.gpsMarker.indicatorColorHex`
- 类型:`string`
- 说明:朝向小三角颜色
- 备注:
- 未配置时按 `colorPreset` 自动映射
### `game.presentation.gpsMarker.showHeadingIndicator`
- 类型:`boolean`
- 说明:是否显示跟随朝向旋转的小三角
- 当前默认值:`true`
- 备注:
- 运行时会结合朝向可信度自动降低透明度
### `game.presentation.gpsMarker.animationProfile`
- 类型:`string`
- 说明GPS 点动画 profile
- 当前支持:
- `minimal`
- `dynamic-runner`
- `warning-reactive`
- 当前默认值:`dynamic-runner`
- 备注:
- 第一阶段主要影响静止、移动、高速和高压状态下的动势强弱
- 未配置时使用系统默认动画逻辑
### `game.presentation.gpsMarker.logoUrl`
- 类型:`string`
- 说明:品牌 logo 资源地址
- 当前状态:已支持中心贴片
- 备注:
- logo 作为中心贴片嵌入 GPS 点,不直接替代定位点
- 建议使用透明背景正方形资源
### `game.presentation.gpsMarker.logoMode`
- 类型:`string`
- 说明logo 嵌入方式
- 当前支持:
- `center-badge`
- 当前状态:已支持
---
## 22. 当前默认逻辑说明
当前客户端对配置的处理原则是:
@@ -642,7 +1059,7 @@
---
## 20. 维护约定
## 23. 维护约定
后续每次新增配置项时,应同步更新:

View File

@@ -0,0 +1,650 @@
# 游戏配置全量模板(当前开发实现版)
本文档提供一份 **截至当前开发状态,客户端已实现或已正式消费的较完整配置模板**
目标:
- 给后端、后台、联调一份“当前最全可用模板”
- 帮助梳理哪些字段已经生效
- 后续新增字段时,以这份模板持续补充
说明:
- 本模板优先以**当前客户端代码真实实现**为准
- 不是未来终态,只代表“当前这一版已经能消费的字段”
- 以顺序赛为主模板,同时说明积分赛差异点
---
## 1. 当前最全模板
```json
{
"schemaVersion": "1",
"version": "2026.03.30",
"app": {
"id": "sample-full-001",
"title": "完整配置示例",
"locale": "zh-CN"
},
"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,
"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": "dialog"
},
"clickExperience": {
"type": "h5",
"url": "https://example.com/content/start-1-click",
"bridge": "content-v1",
"presentation": "dialog"
}
},
"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": "dialog"
},
"clickExperience": {
"type": "h5",
"url": "https://example.com/content/control-1-click",
"bridge": "content-v1",
"presentation": "dialog"
}
},
"control-2": {
"template": "minimal",
"title": "第二检查点",
"body": "这个点配置成手动查看内容。",
"clickTitle": "第二检查点",
"clickBody": "点击查看手动内容。",
"autoPopup": false,
"once": true,
"priority": 1
},
"finish-1": {
"template": "focus",
"title": "比赛结束",
"body": "恭喜完成本次路线。",
"clickTitle": "终点说明",
"clickBody": "点击终点可再次查看结束说明。",
"autoPopup": true,
"once": true,
"priority": 2,
"clickExperience": {
"type": "h5",
"url": "https://example.com/content/finish-1-click",
"bridge": "content-v1",
"presentation": "dialog"
}
}
}
},
"game": {
"mode": "classic-sequential",
"rulesVersion": "1",
"session": {
"startManually": true,
"requiresStartPunch": true,
"requiresFinishPunch": true,
"autoFinishOnLastControl": false,
"maxDurationSec": 5400
},
"punch": {
"policy": "enter-confirm",
"radiusMeters": 5,
"requiresFocusSelection": false
},
"sequence": {
"skip": {
"enabled": true,
"radiusMeters": 30,
"requiresConfirm": true
}
},
"scoring": {
"type": "score",
"defaultControlScore": 10
},
"guidance": {
"showLegs": true,
"legAnimation": true,
"allowFocusSelection": false
},
"visibility": {
"revealFullPlayfieldAfterStartPunch": true
},
"finish": {
"finishControlAlwaysSelectable": false
},
"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
}
}
```
---
## 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.controlOverrides` 字段说明
### key 命名规则
- 起点:`start-1`
- 普通点:`control-1``control-2``control-3`
- 终点:`finish-1`
### 当前支持字段
#### `template`
- 类型:`string`
- 说明:原生内容卡模板
- 当前支持:
- `minimal`
- `story`
- `focus`
#### `score`
- 类型:`number`
- 说明:积分赛点位分值
#### `title`
- 类型:`string`
- 说明:打点完成后自动弹出的标题
#### `body`
- 类型:`string`
- 说明:打点完成后自动弹出的正文
#### `clickTitle`
- 类型:`string`
- 说明:点击点位时弹出的标题
- 默认逻辑:未配置时回退到 `title`
#### `clickBody`
- 类型:`string`
- 说明:点击点位时弹出的正文
- 默认逻辑:未配置时回退到 `body`
#### `autoPopup`
- 类型:`boolean`
- 说明:打点完成后是否自动弹出
- 默认逻辑:`true`
- 特殊逻辑:`game.punch.policy = "enter"` 时不自动弹原生内容
#### `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 内容页展示形态
- 当前支持值:
- `dialog`
- `fullscreen`
#### `clickExperience`
- 类型:`object`
- 说明:点击点位时的 H5 详情/互动扩展配置
- 规则同 `contentExperience`
---
## 7. `game` 字段说明
### `game.mode`
- 类型:`string`
- 说明:玩法模式
- 当前常用值:
- `classic-sequential`
- `score-o`
### `game.rulesVersion`
- 类型:`string`
- 说明:规则版本号
### `game.session.startManually`
- 类型:`boolean`
- 说明:是否手动开始
### `game.session.requiresStartPunch`
- 类型:`boolean`
- 说明:是否必须打起点
### `game.session.requiresFinishPunch`
- 类型:`boolean`
- 说明:是否必须打终点
### `game.session.autoFinishOnLastControl`
- 类型:`boolean`
- 说明:最后一个目标完成后是否自动结束
### `game.session.maxDurationSec`
- 类型:`number`
- 说明:最大对局时长,单位秒
### `game.punch.policy`
- 类型:`string`
- 说明:打点策略
- 当前常用值:
- `enter-confirm`
- `enter`
### `game.punch.radiusMeters`
- 类型:`number`
- 说明:打点半径,单位米
### `game.punch.requiresFocusSelection`
- 类型:`boolean`
- 说明:是否需要先聚焦/选中目标再打点
### `game.sequence.skip.enabled`
- 类型:`boolean`
- 说明:顺序赛是否允许跳点
### `game.sequence.skip.radiusMeters`
- 类型:`number`
- 说明:跳点可用半径
### `game.sequence.skip.requiresConfirm`
- 类型:`boolean`
- 说明:跳点是否需要二次确认
### `game.scoring.type`
- 类型:`string`
- 说明:积分模式类型
- 当前常用值:`score`
### `game.scoring.defaultControlScore`
- 类型:`number`
- 说明:默认控制点分值
### `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
---
## 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",
"guidance": {
"showLegs": false,
"legAnimation": false,
"allowFocusSelection": true
},
"finish": {
"finishControlAlwaysSelectable": true
}
}
}
```
并在 `playfield.controlOverrides` 中为普通点补:
- `score`
---
## 11. 推荐配套阅读
- [D:\dev\cmr-mini\doc\config-template-minimal-game.md](D:/dev/cmr-mini/doc/config-template-minimal-game.md)
- [D:\dev\cmr-mini\doc\config-option-dictionary.md](D:/dev/cmr-mini/doc/config-option-dictionary.md)
- [D:\dev\cmr-mini\doc\config-docs-index.md](D:/dev/cmr-mini/doc/config-docs-index.md)

View File

@@ -0,0 +1,164 @@
# 顺序赛最小配置模板
本文档提供一份 **顺序赛(`classic-sequential`)最小可跑配置模板**
目标:
- 只保留顺序赛跑通所需的最少字段
- 适合快速起活动、联调、排查配置链
- 每个字段都带简要说明
---
## 1. 最小模板
```json
{
"schemaVersion": "1",
"version": "2026.03.30",
"app": {
"id": "sample-classic-minimal-001",
"title": "顺序赛最小示例"
},
"map": {
"tiles": "../map/lxcb-001/tiles/",
"mapmeta": "../map/lxcb-001/tiles/meta.json"
},
"playfield": {
"kind": "course",
"source": {
"type": "kml",
"url": "../kml/lxcb-001/10/c01.kml"
}
},
"game": {
"mode": "classic-sequential",
"punch": {
"policy": "enter-confirm",
"radiusMeters": 5
}
}
}
```
---
## 2. 字段说明
### `schemaVersion`
- 类型:`string`
- 必填:是
- 说明:配置结构版本
- 当前建议值:`"1"`
### `version`
- 类型:`string`
- 必填:是
- 说明:配置版本号
### `app.id`
- 类型:`string`
- 必填:是
- 说明:活动配置实例 ID
### `app.title`
- 类型:`string`
- 必填:是
- 说明:活动标题 / 比赛名称
### `map.tiles`
- 类型:`string`
- 必填:是
- 说明:地图瓦片根路径
### `map.mapmeta`
- 类型:`string`
- 必填:是
- 说明:地图 meta 文件路径
### `playfield.kind`
- 类型:`string`
- 必填:是
- 说明:空间对象类型
- 顺序赛固定使用:`course`
### `playfield.source.type`
- 类型:`string`
- 必填:是
- 说明:空间底稿来源类型
- 当前推荐值:`kml`
### `playfield.source.url`
- 类型:`string`
- 必填:是
- 说明KML 文件路径
### `game.mode`
- 类型:`string`
- 必填:是
- 说明:玩法模式
- 顺序赛固定值:`classic-sequential`
### `game.punch.policy`
- 类型:`string`
- 必填:是
- 说明:打点策略
- 当前常用值:
- `enter-confirm`:进入范围后用户再点击确认打点
- `enter`:进入范围自动打点
### `game.punch.radiusMeters`
- 类型:`number`
- 必填:是
- 说明:打点判定半径,单位米
- 建议默认值:`5`
---
## 3. 当前默认逻辑
如果你不写下面这些字段,顺序赛会按当前客户端默认逻辑运行:
- `map.declination`
- 默认按 `0` 处理
- `map.initialView.zoom`
- 默认由客户端初始视口逻辑接管
- `playfield.CPRadius`
- 默认按客户端内置值处理
- `game.session.*`
- 默认手动开始、要求起点打卡、终点打卡
- `game.sequence.skip.*`
- 默认不启用跳点
- `game.guidance.*`
- 默认使用当前引导逻辑
- `resources.*`
- 默认 profile
- `debug.*`
- 默认关闭
---
## 4. 适用场景
这份模板适合:
- 快速验证顺序赛主流程
- 联调地图和 KML
- 后台先跑通最小顺序赛配置
如果要看更完整版本,请继续参考:
- [D:\dev\cmr-mini\doc\config-template-full-current.md](D:/dev/cmr-mini/doc/config-template-full-current.md)
- [D:\dev\cmr-mini\event\classic-sequential.json](D:/dev/cmr-mini/event/classic-sequential.json)

View File

@@ -0,0 +1,201 @@
# 游戏最小可跑配置模板
本文档提供一份 **去掉大部分选配项之后,当前客户端可以直接跑起来的最小配置模板**
目标:
- 给联调、后台、快速起新活动一个最小起步模板
- 保证只填最必要字段时,也能正常进入地图、开始比赛、完成流程
- 每个字段都带简要说明,方便直接照着改
说明:
- 本模板优先保证“能跑”
- 默认以**顺序赛**作为最小示例
- 如果要做积分赛,只需要替换少量字段
---
## 1. 最小模板
```json
{
"schemaVersion": "1",
"version": "2026.03.30",
"app": {
"id": "sample-minimal-001",
"title": "最小顺序赛示例"
},
"map": {
"tiles": "../map/lxcb-001/tiles/",
"mapmeta": "../map/lxcb-001/tiles/meta.json"
},
"playfield": {
"kind": "course",
"source": {
"type": "kml",
"url": "../kml/lxcb-001/10/c01.kml"
}
},
"game": {
"mode": "classic-sequential",
"punch": {
"policy": "enter-confirm",
"radiusMeters": 5
}
}
}
```
---
## 2. 字段说明
### `schemaVersion`
- 类型:`string`
- 必填:是
- 说明:配置结构版本
- 当前建议值:`"1"`
### `version`
- 类型:`string`
- 必填:是
- 说明:配置版本号
- 建议写法:日期或发布号,例如 `2026.03.30`
### `app.id`
- 类型:`string`
- 必填:是
- 说明:活动配置实例 ID
- 用途:区分不同活动或不同配置版本
### `app.title`
- 类型:`string`
- 必填:是
- 说明:活动标题 / 比赛名称
### `map.tiles`
- 类型:`string`
- 必填:是
- 说明:地图瓦片根路径
### `map.mapmeta`
- 类型:`string`
- 必填:是
- 说明:地图 meta 文件路径
### `playfield.kind`
- 类型:`string`
- 必填:是
- 说明:空间对象类型
- 最小顺序赛推荐值:`course`
- 最小积分赛推荐值:`control-set`
### `playfield.source.type`
- 类型:`string`
- 必填:是
- 说明:空间底稿来源类型
- 当前推荐值:`kml`
### `playfield.source.url`
- 类型:`string`
- 必填:是
- 说明KML 文件路径
### `game.mode`
- 类型:`string`
- 必填:是
- 说明:玩法模式
- 当前常用值:
- `classic-sequential`
- `score-o`
### `game.punch.policy`
- 类型:`string`
- 必填:是
- 说明:打点触发方式
- 当前常用值:
- `enter-confirm`
- `enter`
### `game.punch.radiusMeters`
- 类型:`number`
- 必填:是
- 说明:打点判定半径,单位米
- 建议默认值:`5`
---
## 3. 最小积分赛改法
如果你要把这份最小模板改成积分赛,只需要改这几项:
```json
{
"playfield": {
"kind": "control-set",
"source": {
"type": "kml",
"url": "../kml/lxcb-001/10/c01.kml"
}
},
"game": {
"mode": "score-o",
"punch": {
"policy": "enter-confirm",
"radiusMeters": 5
}
}
}
```
---
## 4. 当前最小模板默认逻辑
即使你没有填写下面这些字段,当前客户端也会按默认逻辑运行:
- `map.declination`
- 默认按 `0` 处理
- `map.initialView.zoom`
- 默认由客户端初始视口逻辑接管
- `playfield.CPRadius`
- 默认按客户端内置值处理
- `game.session.*`
- 使用玩法默认逻辑
- `game.guidance.*`
- 使用当前默认引导逻辑
- `game.visibility.*`
- 使用当前默认可见性逻辑
- `resources.*`
- 使用默认资源 profile
- `debug.*`
- 默认关闭
---
## 5. 适用场景
这份模板适合:
- 新活动快速起盘
- 联调验证地图和 KML 是否正常
- 后台先跑通配置装配链
- 调试客户端主流程是否可进入
如果要做正式项目,请继续参考:
- [D:\dev\cmr-mini\doc\config-template-full-current.md](D:/dev/cmr-mini/doc/config-template-full-current.md)
- [D:\dev\cmr-mini\doc\config-option-dictionary.md](D:/dev/cmr-mini/doc/config-option-dictionary.md)

View File

@@ -0,0 +1,199 @@
# 积分赛最小配置模板
本文档提供一份 **积分赛(`score-o`)最小可跑配置模板**
目标:
- 只保留积分赛跑通所需的最少字段
- 适合快速起活动、联调、排查配置链
- 每个字段都带简要说明
---
## 1. 最小模板
```json
{
"schemaVersion": "1",
"version": "2026.03.30",
"app": {
"id": "sample-score-o-minimal-001",
"title": "积分赛最小示例"
},
"map": {
"tiles": "../map/lxcb-001/tiles/",
"mapmeta": "../map/lxcb-001/tiles/meta.json"
},
"playfield": {
"kind": "control-set",
"source": {
"type": "kml",
"url": "../kml/lxcb-001/10/c01.kml"
}
},
"game": {
"mode": "score-o",
"punch": {
"policy": "enter-confirm",
"radiusMeters": 5
}
}
}
```
---
## 2. 字段说明
### `schemaVersion`
- 类型:`string`
- 必填:是
- 说明:配置结构版本
- 当前建议值:`"1"`
### `version`
- 类型:`string`
- 必填:是
- 说明:配置版本号
### `app.id`
- 类型:`string`
- 必填:是
- 说明:活动配置实例 ID
### `app.title`
- 类型:`string`
- 必填:是
- 说明:活动标题 / 比赛名称
### `map.tiles`
- 类型:`string`
- 必填:是
- 说明:地图瓦片根路径
### `map.mapmeta`
- 类型:`string`
- 必填:是
- 说明:地图 meta 文件路径
### `playfield.kind`
- 类型:`string`
- 必填:是
- 说明:空间对象类型
- 积分赛固定使用:`control-set`
### `playfield.source.type`
- 类型:`string`
- 必填:是
- 说明:空间底稿来源类型
- 当前推荐值:`kml`
### `playfield.source.url`
- 类型:`string`
- 必填:是
- 说明KML 文件路径
### `game.mode`
- 类型:`string`
- 必填:是
- 说明:玩法模式
- 积分赛固定值:`score-o`
### `game.punch.policy`
- 类型:`string`
- 必填:是
- 说明:打点策略
- 当前常用值:
- `enter-confirm`
- `enter`
### `game.punch.radiusMeters`
- 类型:`number`
- 必填:是
- 说明:打点判定半径,单位米
- 建议默认值:`5`
---
## 3. 当前默认逻辑
如果你不写下面这些字段,积分赛会按当前客户端默认逻辑运行:
- `map.declination`
- 默认按 `0` 处理
- `map.initialView.zoom`
- 默认由客户端初始视口逻辑接管
- `playfield.CPRadius`
- 默认按客户端内置值处理
- `playfield.controlOverrides.*.score`
- 没配时走 `game.scoring.defaultControlScore` 或玩法默认值
- `game.session.*`
- 默认手动开始
- `game.guidance.allowFocusSelection`
- 默认按积分赛逻辑允许选点
- `game.finish.finishControlAlwaysSelectable`
- 默认按积分赛逻辑处理终点可选
- `resources.*`
- 默认 profile
- `debug.*`
- 默认关闭
---
## 4. 推荐补充字段
如果你要让积分赛更接近正式活动,通常很快会补这几项:
```json
{
"playfield": {
"controlOverrides": {
"control-1": {
"score": 10
},
"control-2": {
"score": 20
}
}
},
"game": {
"scoring": {
"type": "score",
"defaultControlScore": 10
},
"guidance": {
"allowFocusSelection": true
},
"finish": {
"finishControlAlwaysSelectable": true
}
}
}
```
---
## 5. 适用场景
这份模板适合:
- 快速验证积分赛主流程
- 联调自由选点、积分累加、终点结束
- 后台先跑通最小积分赛配置
如果要看更完整版本,请继续参考:
- [D:\dev\cmr-mini\doc\config-template-full-current.md](D:/dev/cmr-mini/doc/config-template-full-current.md)
- [D:\dev\cmr-mini\event\score-o.json](D:/dev/cmr-mini/event/score-o.json)

View File

@@ -0,0 +1,210 @@
# GPS 点动画系统方案
## 目标
把 GPS 点从“静态定位点”升级成**状态驱动的动态标记系统**
- 停止时是一种动画
- 移动时是一种动画
- 高速时是一种动画
- 高压/危险状态时还能叠加额外张力
原则:
- 优先程序化动画,不先上重资源
- 不破坏当前位置识别性
- 必须兼容 `standard / lite`
- 品牌 logo 只是贴片,不替代定位点本体和朝向三角
## 状态分层
### 1. 运动状态
- `idle`
- 基本静止
- 轻呼吸
- 不拖尾
- `moving`
- 正常行走/跑动
- 有轻微动势和尾迹
- `fast-moving`
- 明显高速
- 更强脉冲
- 更长尾迹
- 朝向更锐利
### 2. 危险/高压状态
- `warning`
- 由心率/张力状态触发
- 不替代运动判断,而是在视觉上给 GPS 点额外警示感
- 更暖的色彩张力
- 更强的外环脉冲
## 第一阶段实现范围
### 默认动画 profile
- `dynamic-runner`
后续预留:
- `minimal`
- `warning-reactive`
### 第一阶段具体表现
#### `idle`
- 慢节奏呼吸
- 基本无拖尾
- 方向三角稍收敛
#### `moving`
- 普通脉冲
- 后侧轻尾迹
- 方向三角略放大
#### `fast-moving`
- 更快脉冲
- 更长尾迹
- 本体略放大
- 方向三角更强
#### `warning`
- 保留运动态基础
- 外环增加暖色警示张力
- 脉冲节奏更急
## 第一阶段配置字段
入口:
```json
"game": {
"presentation": {
"gpsMarker": {}
}
}
```
新增字段:
```json
{
"animationProfile": "dynamic-runner"
}
```
说明:
- `minimal`
- 更轻、更克制
- 适合低配或保守活动风格
- `dynamic-runner`
- 默认值
- 强调移动感
- `warning-reactive`
- 更强调高压/危险张力
## 运行时内部字段
这些字段不建议先暴露给活动配置,而是由运行时自动计算:
- `motionState`
- `motionIntensity`
- `wakeStrength`
- `warningGlowStrength`
- `indicatorScale`
- `logoScale`
这样可以保证:
- 配置简单
- 逻辑稳定
- 真机调完后再决定哪些值得开放
## 运行时判定建议
### 运动状态
- `< 1.0 km/h``idle`
- `1.0 ~ 6.8 km/h``moving`
- `>= 6.8 km/h``fast-moving`
### 高压状态
参考现有 telemetry tone
- `yellow`
- `orange`
- `red`
其中:
- `orange / red`
优先进入 `warning`
- `yellow`
作为较轻的张力增强
## 渲染拆分
### WebGL 主体
负责:
- 本体
- 外环
- 脉冲
- 尾迹
- 朝向三角
### 2D 叠加层
负责:
- logo 中心贴片
logo 不参与主几何动画,只跟随缩放强度和尺寸变化。
## 性能策略
### `standard`
- 完整脉冲
- 完整尾迹
- 警示外环
### `lite`
- 减弱尾迹
- 降低 glow
- 降低 warning 外环强度
- 保留最基本的移动/静止差异
## 后续第二阶段
- logo 贴片本身的轻动画
- 事件动作
- 打点成功跳动
- 锁定开启反馈
- 高压进入反馈
- mascot/角色化 GPS 点
## 结论
GPS 点动画不应该做成单一固定动画,而应该做成:
**状态驱动的动态标记系统**
第一阶段先把:
- `idle`
- `moving`
- `fast-moving`
- `warning`
这 4 种状态的程序化动画跑通,再决定后续是否继续开放更细粒度配置。

View File

@@ -0,0 +1,113 @@
# GPS 点样式系统方案
## 目标
把当前“粗糙蓝点”升级成正式的 GPS 点样式系统,满足:
- 默认样式更精致
- 显示/隐藏可控
- 大小可调
- 颜色可调
- 带跟随朝向旋转的小三角
- 后续可承接品牌 logo 定制
## 分层
### 1. 显示策略
- `visible`
- `size`
- `colorPreset`
### 2. 基础样式
第一阶段支持:
- `dot`
- `beacon`
- `disc`
- `badge`
默认:
- `beacon`
### 3. 朝向指示
GPS 点上方增加一个小三角:
- 跟随朝向旋转
- 朝向可信度高时更明显
- 朝向可信度低时自动降低透明度
### 4. 品牌化扩展
后续通过:
- `logoUrl`
- `logoMode`
把商家 logo 作为中心贴片嵌入 GPS 点,不直接替代定位点本体。
## 第一阶段默认值
```json
{
"visible": true,
"style": "beacon",
"size": "medium",
"colorPreset": "cyan",
"showHeadingIndicator": true,
"logoUrl": "",
"logoMode": "center-badge"
}
```
## 用户设置建议
系统设置先开放:
- GPS 点显示:`显示 / 隐藏`
- GPS 点大小:`小 / 中 / 大`
- GPS 点颜色8 种亮色
品牌 logo 先不进用户设置,只保留给活动配置。
## 配置入口
建议统一放在:
```json
"game": {
"presentation": {
"gpsMarker": {}
}
}
```
## 长期演进
### 第二阶段
- logo 中心贴片
- 不同玩法默认 GPS 点 profile
- 更强的脉冲/光晕动画
### 第三阶段
- GPS 点与心率/危险状态联动
- 客户品牌化主题包
- 特殊活动皮肤
## 结论
GPS 点应被视为独立样式系统,而不是固定蓝点。
第一阶段先把:
- 显示
- 大小
- 颜色
- 朝向三角
做稳定,再逐步承接商业品牌化定制。

View File

@@ -0,0 +1,125 @@
# 模拟器调试日志方案
## 目标
复用现有 GPS 模拟器 websocket在不污染地图调试面板的前提下把高频、临时、开发期日志输出到外部模拟器。
第一阶段只做最小闭环:
- 复用 `tools/mock-gps-sim` 现有 websocket
- 增加 `debug-log` 消息类型
- 小程序侧增加最小 logger
- 第一批只发送 `gps-logo` 范围日志
## 设计原则
- 调试面板看“当前状态”
- 模拟器日志看“变化过程”
- 日志链只在开发/调试期间启用
- 不进入正式玩法逻辑
- 不把高频临时日志继续塞进页面 WXML
## 协议
消息类型:
```json
{
"type": "debug-log",
"timestamp": 1712345678901,
"scope": "gps-logo",
"level": "info",
"message": "wx.getImageInfo success",
"payload": {
"src": "https://example.com/logo.png",
"path": "wxfile://tmp_xxx"
}
}
```
字段说明:
- `type`
固定为 `debug-log`
- `timestamp`
毫秒时间戳
- `scope`
日志分类,例如 `gps-logo``h5``compass`
- `level`
`info / warn / error`
- `message`
简短可读说明
- `payload`
可选附加对象,用于排查细节
## 第一阶段 scope
第一批只接:
- `gps-logo`
典型日志点:
- logo 未配置
- 当前风格不是 `badge`
- 开始加载 logo
- `wx.getImageInfo` 成功
- `wx.getImageInfo` 失败
- 图片 `onload`
- 图片 `onerror`
## 小程序侧实现
新增:
- `miniprogram/engine/debug/mockSimulatorDebugLogger.ts`
职责:
- 复用 mock GPS simulator websocket 地址
- 负责连接、断开、简单队列、发送 `debug-log`
- 只在调试 UI 开启时启用
接入点:
- `MapEngine`
- 调试 UI 开启时启用 logger
- 调试 UI 关闭时关闭 logger
- mock bridge 地址变化时同步 logger 地址
- `CourseLabelRenderer`
- 发送 `gps-logo` 相关日志
## 模拟器侧实现
复用:
- `tools/mock-gps-sim/server.js`
- `tools/mock-gps-sim/public/index.html`
- `tools/mock-gps-sim/public/simulator.js`
最小能力:
- websocket 接收 `debug-log`
- UI 新增“调试日志”区域
- 仅显示 `debug-log`
- 保留最近若干条,避免无限增长
## 后续扩展
第二阶段可以再补:
- `compass`
- `h5`
- `content-card`
- `heart-rate`
第三阶段再补:
- scope 过滤
- level 过滤
- 暂停滚动
- 导出日志
## 当前结论
先把 `gps-logo` 调试链打通,再回头用模拟器日志查 logo 为什么不显示,比继续把临时字段堆在调试面板里更稳。

View File

@@ -0,0 +1,85 @@
# 轨迹可视化方案
本文档定义用户轨迹的显示模式、默认策略与配置结构。
目标:
- 支持 `none / full / tail` 三种轨迹模式
- `tail` 模式有更强的实时感和游戏感
- 兼顾低端机性能
## 模式定义
### `none`
- 不显示轨迹
- 只显示当前 GPS 点
### `full`
- 显示从开始到当前的完整轨迹
### `tail`
- 只显示最近一小段拖尾轨迹
- 头部更亮、更粗
- 尾部逐步变淡、变细
- 用户停止移动后,轨迹会逐步缩短到消失
## 推荐默认值
### 顺序赛
- `mode = full`
- `style = classic`
### 积分赛
- `mode = tail`
- `style = neon`
## 推荐配置
```json
"game": {
"presentation": {
"track": {
"mode": "tail",
"style": "neon",
"tailMeters": 60,
"tailMaxSeconds": 30,
"fadeOutWhenStill": true,
"stillSpeedKmh": 0.6,
"fadeOutDurationMs": 3000,
"colorHex": "#176d5d",
"headColorHex": "#54f3d8",
"widthPx": 5,
"headWidthPx": 10,
"glowStrength": 0.42
}
}
}
```
## 当前实现约定
当前第一版实现支持:
- `mode`
- `style`
- `tailMeters`
- `tailMaxSeconds`
- `fadeOutWhenStill`
- `stillSpeedKmh`
- `fadeOutDurationMs`
- `colorHex`
- `headColorHex`
- `widthPx`
- `headWidthPx`
- `glowStrength`
## 后续扩展
- 轨迹颜色按心率区间变化
- 轨迹颜色按速度变化
- `standard / lite` 下自动降级 glow