本文档用于整理当前阶段推荐的配置文件设计方案,供后端、客户端和后台管理设计参考。
目标是让配置真正成为游戏的驱动入口,同时兼顾后续多玩法、多资源、多活动复用。
配置文件系统需要解决以下问题:
当前推荐原则:
当前推荐主入口配置结构如下:
{
"schemaVersion": "1",
"version": "2026.03.25",
"app": {},
"map": {},
"playfield": {},
"game": {},
"resources": {},
"debug": {}
}
各层职责如下:
app
活动级或应用级基础信息map
地图底图和空间底座playfield
当前玩法使用的空间对象定义game
当前玩法规则配置resources
资源包与 profiledebug
调试与开发开关在定向语义里,course 是准确术语,表示路线。
但从系统长期扩展看,course 并不是所有玩法的上位概念。
例如:
course因此推荐:
playfieldcourse 只作为 playfield.kind 的一种例如:
{
"playfield": {
"kind": "course"
}
}
或:
{
"playfield": {
"kind": "control-set"
}
}
当前推荐边界非常明确:
KML 适合描述:
配置负责描述:
一句话总结:
KML 描述空间事实,配置描述玩法解释。
app用于活动级基础信息。
示例:
{
"app": {
"id": "lxcb-001",
"title": "雪熊领秀城区定向赛",
"locale": "zh-CN"
}
}
map用于地图底图与空间底座。
示例:
{
"map": {
"tiles": "lxcb-001/tiles/",
"mapmeta": "lxcb-001/tiles/meta.json",
"declination": 6.91,
"initialView": {
"zoom": 17
}
}
}
playfield用于描述当前玩法使用的空间对象及其来源。
示例:
{
"playfield": {
"kind": "course",
"source": {
"type": "kml",
"url": "lxcb-001/course/c01.kml"
},
"CPRadius": 6,
"controlOverrides": {},
"metadata": {}
}
}
建议后续逐步支持的对象包括:
controlscollectibleszoneshazardslinksspawnPointsgame用于描述玩法规则。
推荐统一结构如下:
{
"game": {
"mode": "",
"rulesVersion": "1",
"session": {},
"punch": {},
"scoring": {},
"guidance": {},
"visibility": {},
"finish": {},
"telemetry": {},
"feedback": {}
}
}
session控制一局游戏的流程参数:
punch控制打点规则:
scoring控制积分与结算:
guidance控制引导方式:
visibility控制显隐逻辑:
finish控制结束规则:
telemetry控制通用运动信息参数:
feedback控制反馈 profile:
resources用于描述资源 profile。
示例:
{
"resources": {
"audioProfile": "default",
"contentProfile": "default",
"themeProfile": "default-race"
}
}
当前阶段建议先保持轻量,后续再逐步拆成资源包 manifest。
debug用于开发和调试相关开关。
示例:
{
"debug": {
"allowModeSwitch": false,
"allowMockInput": false,
"allowSimulator": false
}
}
{
"schemaVersion": "1",
"version": "2026.03.25",
"app": {
"id": "lxcb-001",
"title": "雪熊领秀城区顺序赛"
},
"map": {
"tiles": "lxcb-001/tiles/",
"mapmeta": "lxcb-001/tiles/meta.json",
"declination": 6.91
},
"playfield": {
"kind": "course",
"source": {
"type": "kml",
"url": "lxcb-001/course/c01.kml"
},
"CPRadius": 6
},
"game": {
"mode": "classic-sequential",
"rulesVersion": "1",
"session": {
"requiresStartPunch": true,
"requiresFinishPunch": true,
"autoFinishOnLastControl": false,
"startManually": true
},
"punch": {
"policy": "enter-confirm",
"radiusMeters": 10
},
"guidance": {
"showLegs": true,
"legAnimation": true,
"allowFocusSelection": false
},
"visibility": {
"revealFullPlayfieldAfterStartPunch": true
},
"telemetry": {
"heartRate": {
"age": 30,
"restingHeartRateBpm": 62,
"userWeightKg": 65
}
},
"feedback": {
"audioProfile": "default",
"hapticsProfile": "default",
"uiEffectsProfile": "default"
}
},
"resources": {
"audioProfile": "default",
"contentProfile": "default"
},
"debug": {
"allowModeSwitch": false,
"allowMockInput": false
}
}
{
"schemaVersion": "1",
"version": "2026.03.25",
"app": {
"id": "lxcb-001",
"title": "雪熊领秀城区积分赛"
},
"map": {
"tiles": "lxcb-001/tiles/",
"mapmeta": "lxcb-001/tiles/meta.json",
"declination": 6.91
},
"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 }
}
},
"game": {
"mode": "score-o",
"rulesVersion": "1",
"session": {
"requiresStartPunch": true,
"requiresFinishPunch": false,
"startManually": true
},
"punch": {
"policy": "enter-confirm",
"radiusMeters": 10,
"requiresFocusSelection": true
},
"guidance": {
"showLegs": false,
"legAnimation": false,
"allowFocusSelection": true
},
"scoring": {
"type": "score"
},
"finish": {
"finishControlAlwaysSelectable": true
},
"telemetry": {
"heartRate": {
"age": 30,
"restingHeartRateBpm": 62,
"userWeightKg": 65
}
},
"feedback": {
"audioProfile": "default",
"hapticsProfile": "default",
"uiEffectsProfile": "default"
}
},
"resources": {
"audioProfile": "default",
"contentProfile": "default"
},
"debug": {
"allowModeSwitch": false,
"allowMockInput": false
}
}
map -> map.tilesmapmeta -> map.mapmetadeclination -> map.declinationcourse -> playfield.source.urlCPRadius -> playfield.CPRadiusgame.mode -> game.modegame.punchPolicy -> game.punch.policyPunchRadius -> game.punch.radiusMetersgame.autoFinishOnLastControl -> game.session.autoFinishOnLastControlgame.telemetry.age -> game.telemetry.heartRate.agegame.telemetry.restingHeartRateBpm -> game.telemetry.heartRate.restingHeartRateBpmgame.telemetry.userWeightKg -> game.telemetry.heartRate.userWeightKggame.audio -> game.feedback.audio 或 resources.audioProfilesgame.haptics -> game.feedback.haptics 或 resources.hapticsProfilesgame.uiEffects -> game.feedback.uiEffects 或 resources.uiEffectsProfiles当前建议迁移策略:
当前阶段主配置建议先保持单文件。
但未来配置规模变大时,推荐升级成多 manifest 组合:
{
"schemaVersion": "1",
"version": "2026.03.25",
"map": {
"manifest": "maps/lxcb-001/map.json"
},
"playfield": {
"manifest": "playfields/lxcb-001/c01.json"
},
"game": {
"manifest": "modes/score-o/default.json"
},
"resources": {
"manifest": "packs/spring-2026/resources.json"
},
"debug": {}
}
这样可以支持:
后续从服务端和后台管理的复用角度,建议围绕以下核心对象建模:
MapPlayfieldGameModeResourcePackEvent其中:
Map
地图底图与空间底座Playfield
当前玩法场景中的空间对象定义GameMode
玩法规则模板ResourcePack
资源包与 profileEvent
一次实际发布的活动实例推荐关系可以理解为:
Event = Map + Playfield + GameMode + ResourcePack + 发布参数
当前阶段最推荐的方案是:
game.jsonapp / map / playfield / game / resources / debugcourse 成为总抽象,而是提升为更通用的 playfield一句话总结:
KML 描述空间事实,配置描述玩法解释;主配置按 map / playfield / game / resources / debug 分层,后续再升级成 manifest 组合。