docs: add battle system, conditional routing, key moments, and creators guide docs
This commit is contained in:
112
docs/guide/BATTLE_SYSTEM.md
Normal file
112
docs/guide/BATTLE_SYSTEM.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# 战斗系统
|
||||
|
||||
## 概述
|
||||
|
||||
P31 新增。分为两个独立功能:**战斗 HUD**(战斗中显示)和**战斗结算**(胜利后弹出)。
|
||||
|
||||
---
|
||||
|
||||
## BattleHUD — 战斗中显示的角色属性
|
||||
|
||||
配置在 `SceneNode.battleHUD`。
|
||||
|
||||
```json
|
||||
{
|
||||
"battleHUD": [
|
||||
{
|
||||
"label": "主角",
|
||||
"labelKey": "battle.hud.player",
|
||||
"portrait": "images/player.jpg",
|
||||
"stats": [
|
||||
{ "variable": "player_hp", "label": "HP", "labelKey": "stat.hp", "max": 100 },
|
||||
{ "variable": "player_mp", "label": "MP", "labelKey": "stat.mp", "max": 50 },
|
||||
{ "variable": "score", "label": "连击", "labelKey": "stat.combo" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
| stat 字段 | 说明 |
|
||||
|-----------|------|
|
||||
| `variable` | 变量名,值随 effect 实时变化 |
|
||||
| `label` | 显示标签(回退值) |
|
||||
| `labelKey` | i18n key |
|
||||
| `max` | 最大值,有则为进度条,无则为纯数字 |
|
||||
| `style` | 强制 `"bar"` 或 `"number"`。没配时根据有无 `max` 自动 |
|
||||
|
||||
进度条颜色根据百分比自动变化:100-50% 绿色 / 50-25% 橙色 / 25-0% 红色。
|
||||
|
||||
---
|
||||
|
||||
## BattleResult — 胜利结算面板
|
||||
|
||||
配置在 `SceneNode.battleResult`。视频播放完后自动弹出。
|
||||
|
||||
```json
|
||||
{
|
||||
"battleResult": {
|
||||
"title": "击退成功!",
|
||||
"titleKey": "battle.result.victory",
|
||||
"stats": [
|
||||
{ "label": "勇气", "labelKey": "stat.courage", "variable": "courage", "max": 100 },
|
||||
{ "label": "QTE 成功", "labelKey": "stat.qte_succeeded", "variable": "qte_succeeded" }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `title` | 结算标题(回退值) |
|
||||
| `titleKey` | 标题 i18n key |
|
||||
| `stats` | 统计项数组。`variable` / `label` / `labelKey` / `max` |
|
||||
|
||||
### 关键规则
|
||||
|
||||
- 战败场景**不配** `battleResult`——战败直接走视频叙事
|
||||
- 结算面板关闭后自动跳转到 `nextScene` 或第一项 `choice` 目标
|
||||
- stats 数量随意增减,面板自动适配
|
||||
|
||||
---
|
||||
|
||||
## 完整模板
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "combat",
|
||||
"videoUrl": "combat/video.mp4",
|
||||
"battleHUD": [ ... ],
|
||||
"qte": {
|
||||
"successScene": "combat_router",
|
||||
"failScene": "defeat",
|
||||
"effects": {
|
||||
"success": [{ "type": "add", "target": "enemy_hp", "value": -25 }],
|
||||
"fail": [{ "type": "add", "target": "player_hp", "value": -20 }]
|
||||
}
|
||||
},
|
||||
"nextScene": "combat_router"
|
||||
},
|
||||
{
|
||||
"id": "combat_router",
|
||||
"keyMoment": false,
|
||||
"nextScene": [
|
||||
{ "conditions": [{ "variable": "enemy_hp", "op": "<=", "value": 0 }], "targetScene": "victory" },
|
||||
{ "conditions": [{ "variable": "player_hp", "op": "<=", "value": 0 }], "targetScene": "defeat" },
|
||||
{ "targetScene": "combat" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "victory",
|
||||
"videoUrl": "victory/video.mp4",
|
||||
"battleResult": { "title": "胜利!", "stats": [ ... ] },
|
||||
"nextScene": "next_chapter"
|
||||
},
|
||||
{
|
||||
"id": "defeat",
|
||||
"videoUrl": "defeat/video.mp4",
|
||||
"keyMoment": true,
|
||||
"onEnter": [{ "type": "set", "target": "player_dead", "value": 1 }],
|
||||
"nextScene": "game_over"
|
||||
}
|
||||
```
|
||||
36
docs/guide/CONDITIONAL_ROUTING.md
Normal file
36
docs/guide/CONDITIONAL_ROUTING.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# 条件路由
|
||||
|
||||
## 概述
|
||||
|
||||
P25 新增。`nextScene` 从单一场景 ID 扩展为**条件路由数组**。
|
||||
第一个满足 `conditions` 的场景自动跳转,末尾无条件项作为默认兜底。
|
||||
|
||||
## 基本用法
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "combat_router",
|
||||
"keyMoment": false,
|
||||
"nextScene": [
|
||||
{ "conditions": [{ "variable": "enemy_hp", "op": "<=", "value": 0 }], "targetScene": "victory" },
|
||||
{ "conditions": [{ "variable": "player_hp", "op": "<=", "value": 0 }], "targetScene": "defeat" },
|
||||
{ "targetScene": "combat" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**解读:** 敌人 HP ≤ 0 → 胜利 / 自己 HP ≤ 0 → 战败 / 否则 → 回到战斗场景循环。
|
||||
|
||||
## 配合 QTE 使用
|
||||
|
||||
```
|
||||
QTE 成功 → effects: enemy_hp -= 25
|
||||
→ successScene = "combat_router"
|
||||
├── enemy_hp <= 0 → victory 场景
|
||||
├── player_hp <= 0 → defeat 场景
|
||||
└── 否则 → 回到 QTE 场景(循环)
|
||||
```
|
||||
|
||||
## 向后兼容
|
||||
|
||||
旧的 `"nextScene": "alone_ending"` 写法**完全不受影响**。引擎自动区分字符串和数组。
|
||||
15
docs/guide/CREATORS_GUIDE.md
Normal file
15
docs/guide/CREATORS_GUIDE.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# 创作者指南
|
||||
|
||||
本文档集涵盖所有剧作和功能配置的教程。
|
||||
|
||||
| 文档 | 说明 |
|
||||
|------|------|
|
||||
| [QUICK_START.md](QUICK_START.md) | 快速上手——5 分钟跑通第一个场景 |
|
||||
| [SCENE_JSON_SPEC.md](SCENE_JSON_SPEC.md) | 所有字段的完整参考手册 |
|
||||
| [BRANCHING.md](BRANCHING.md) | 基本分支、条件分支、隐藏选项 |
|
||||
| [CONDITIONAL_ROUTING.md](CONDITIONAL_ROUTING.md) | `nextScene` 数组——条件路由(P25) |
|
||||
| [KEY_MOMENTS.md](KEY_MOMENTS.md) | StoryGallery 关键节点过滤(P26) |
|
||||
| [BATTLE_SYSTEM.md](BATTLE_SYSTEM.md) | 战斗 HUD + 战斗结算面板(P31) |
|
||||
| [INTERACTIONS.md](INTERACTIONS.md) | QTE、热点、循环等待 |
|
||||
| [I18N.md](I18N.md) | 多语言字幕和 UI 国际化 |
|
||||
| [PUBLISHING.md](PUBLISHING.md) | 打包发布——Web zip / macOS / Windows |
|
||||
31
docs/guide/KEY_MOMENTS.md
Normal file
31
docs/guide/KEY_MOMENTS.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# 关键节点过滤
|
||||
|
||||
## 概述
|
||||
|
||||
P26 新增。StoryGallery 的章节回顾默认只展示**剧情关键节点**,过滤掉过渡/路由/中间场景。
|
||||
|
||||
## 自动判断规则
|
||||
|
||||
| 场景类型 | 是否展示 |
|
||||
|----------|:--:|
|
||||
| 章节起始场景(`chapters[].startScene`) | ✅ |
|
||||
| 有 `choices` 的分支点 | ✅ |
|
||||
| 结局场景(`endings[].sceneId`) | ✅ |
|
||||
| QTE 场景 | ❌ |
|
||||
| 路由/过渡场景 | ❌ |
|
||||
|
||||
## 手动覆盖:`keyMoment` 字段
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "combat_router",
|
||||
"keyMoment": false,
|
||||
"nextScene": [...]
|
||||
}
|
||||
```
|
||||
|
||||
| 值 | 行为 |
|
||||
|:--:|------|
|
||||
| `true` | 强制展示 |
|
||||
| `false` | 强制隐藏 |
|
||||
| 未设置 | 自动判断 |
|
||||
@@ -48,7 +48,7 @@ interface SceneNode {
|
||||
choices?: Choice[]
|
||||
hotspots?: Hotspot[]
|
||||
qte?: QTEDefinition
|
||||
nextScene?: string
|
||||
nextScene?: string | Choice[]
|
||||
onEnter?: Effect[]
|
||||
loopStart?: number
|
||||
loopEnd?: number
|
||||
@@ -59,6 +59,9 @@ interface SceneNode {
|
||||
bgmDuckFade?: number
|
||||
videoMuted?: boolean
|
||||
skippable?: boolean
|
||||
keyMoment?: boolean
|
||||
battleHUD?: BattleHUDEntry[]
|
||||
battleResult?: BattleResultDef
|
||||
}
|
||||
```
|
||||
|
||||
@@ -76,7 +79,7 @@ interface SceneNode {
|
||||
| `choices` | Choice[] | 选项列表 |
|
||||
| `hotspots` | Hotspot[] | 可点击热点区域 |
|
||||
| `qte` | QTEDefinition | QTE 定义 |
|
||||
| `nextScene` | string | 无选项时的默认跳转场景 |
|
||||
| `nextScene` | string \| Choice[] | 无选项时的默认跳转。字符串为单一场景 ID;数组为条件路由,遍历第一个满足 conditions 的跳转。末尾无条件项作为默认目标 |
|
||||
| `onEnter` | Effect[] | 进入场景时触发的效果 |
|
||||
| `loopStart` | number | 循环起始时间(秒) |
|
||||
| `loopEnd` | number | 循环结束时间(秒)。视频播放到 loopEnd 时跳回 loopStart |
|
||||
@@ -87,6 +90,9 @@ interface SceneNode {
|
||||
| `bgmDuckFade` | number | BGM Duck 过渡时长(秒),默认 0.5 |
|
||||
| `videoMuted` | boolean | 视频静音(配合独立 BGM 使用) |
|
||||
| `skippable` | boolean | `false` = 禁止跳过(用于 QTE 等关键场景) |
|
||||
| `keyMoment` | boolean | StoryGallery 中是否展示为关键节点。`true`=强制展示,`false`=强制隐藏,未设置时自动判断(章节起始/有 choice/是结局) |
|
||||
| `battleHUD` | BattleHUDEntry[] | 战斗场景中显示的角色属性 HUD。每个 entry 为一个角色(头像 + stats 列表) |
|
||||
| `battleResult` | BattleResultDef | 胜利结算面板。视频结束后弹出,展示战斗统计数据。战败场景不配置此字段 |
|
||||
|
||||
---
|
||||
|
||||
@@ -111,7 +117,6 @@ interface Choice {
|
||||
| `textKey` | i18n key,优先于 `text`。如 `"intro.choice.left_door"` |
|
||||
| `prompt` | 选择后浮现的提示文字(回退值) |
|
||||
| `promptKey` | prompt 的 i18n key。如 `"left_door.prompt.handshake"`。优先于 `prompt` |
|
||||
| `promptKey` | prompt 的 i18n key。如 `"left_door.prompt.handshake"` |
|
||||
| `targetScene` | 目标场景 ID |
|
||||
| `conditions` | 显示条件,不满足的选项隐藏 |
|
||||
| `effects` | 选择后触发的效果 |
|
||||
@@ -178,7 +183,6 @@ interface QTEDefinition {
|
||||
| `triggerTime` | 触发时间(秒),视频播放到此时间弹出 QTE |
|
||||
| `prompt` | 提示文字(回退值) |
|
||||
| `promptKey` | i18n key。如 `"right_door.qte.dodge"`。优先于 `prompt` |
|
||||
| `promptKey` | i18n key。如 `"right_door.qte.dodge"` |
|
||||
| `keys` | 有效按键列表,如 `["ArrowLeft", "ArrowRight", "a", "d"]` |
|
||||
| `timeLimit` | 限时秒数 |
|
||||
| `successScene` | 成功跳转场景 |
|
||||
@@ -295,3 +299,56 @@ interface LocalesConfig {
|
||||
|------|------|
|
||||
| `path` | 语言文件目录(相对于 `assetBase`),如 `"locales/"` |
|
||||
| `languages` | 支持的语言列表,如 `["zh", "en", "ja"]` |
|
||||
|
||||
### BattleHUDEntry / BattleHUDStat
|
||||
|
||||
战斗场景中显示的角色属性 HUD。配置在 `SceneNode.battleHUD`。
|
||||
|
||||
```typescript
|
||||
interface BattleHUDEntry {
|
||||
label: string
|
||||
labelKey?: string
|
||||
portrait?: string
|
||||
stats: BattleHUDStat[]
|
||||
}
|
||||
|
||||
interface BattleHUDStat {
|
||||
variable: string
|
||||
label: string
|
||||
labelKey?: string
|
||||
max?: number
|
||||
style?: 'bar' | 'number'
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `label` | 角色名称(回退值) |
|
||||
| `labelKey` | 角色名称 i18n key |
|
||||
| `portrait` | 角色头像路径 |
|
||||
| `stats` | 属性数组。`variable`/`label`/`labelKey`/`max`/`style`。`style` 缺省时根据有无 `max` 自动判断(有则为 bar,无则为 number) |
|
||||
|
||||
### BattleResultDef / BattleResultStat
|
||||
|
||||
战斗胜利结算面板。配置在 `SceneNode.battleResult`。
|
||||
|
||||
```typescript
|
||||
interface BattleResultDef {
|
||||
title: string
|
||||
titleKey?: string
|
||||
stats: BattleResultStat[]
|
||||
}
|
||||
|
||||
interface BattleResultStat {
|
||||
label: string
|
||||
labelKey?: string
|
||||
variable: string
|
||||
max?: number
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `title` | 结算标题(回退值) |
|
||||
| `titleKey` | 标题 i18n key |
|
||||
| `stats` | 统计项数组。`variable`/`label`/`labelKey`/`max` |
|
||||
|
||||
Reference in New Issue
Block a user