chore: initial commit
This commit is contained in:
248
Docs/DesignSpec/14_NarrativeSystem.md
Normal file
248
Docs/DesignSpec/14_NarrativeSystem.md
Normal file
@@ -0,0 +1,248 @@
|
||||
# 14 · 叙事系统规范
|
||||
|
||||
> **所属文档集** [← 返回索引](./README.md)
|
||||
> **摘要**:对话系统、世界标记、NPC 状态管理与三结局触发逻辑。
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [叙事设计原则](#1-叙事设计原则)
|
||||
2. [对话系统](#2-对话系统)
|
||||
3. [世界标记系统](#3-世界标记系统)
|
||||
4. [NPC 状态管理](#4-npc-状态管理)
|
||||
5. [任务系统](#5-任务系统)
|
||||
6. [结局触发系统](#6-结局触发系统)
|
||||
7. [叙事事件目录](#7-叙事事件目录)
|
||||
|
||||
---
|
||||
|
||||
## 1. 叙事设计原则
|
||||
|
||||
| 原则 | 说明 |
|
||||
|------|------|
|
||||
| **环境叙事优先** | 通过场景、图鉴和道具描述讲述故事,减少强制对话 |
|
||||
| **非线性探索** | 玩家可按任意顺序解锁叙事内容 |
|
||||
| **状态感知** | NPC 的对话随玩家进程改变(不重复同一句话)|
|
||||
| **数据驱动** | 所有对话树、条件和触发均为数据,不硬编码 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 对话系统
|
||||
|
||||
### 2.1 对话数据模型
|
||||
|
||||
```
|
||||
DataModel DialogueData {
|
||||
dialogueId : ID
|
||||
speakerId : ID // NPC ID 或 "player"
|
||||
──────────────────────────────────
|
||||
nodes : List<DialogueNode>
|
||||
entryNodeId : ID // 起始节点
|
||||
}
|
||||
|
||||
DataModel DialogueNode {
|
||||
nodeId : ID
|
||||
type : DialogueNodeType // Text / Choice / Condition / Action
|
||||
──────────────────────────────────
|
||||
// type = Text:
|
||||
text : Optional<String> // 支持本地化 Key
|
||||
portrait : Optional<PortraitID>
|
||||
nextNodeId : Optional<ID> // null = 对话结束
|
||||
|
||||
// type = Choice:
|
||||
choices : Optional<List<DialogueChoice>>
|
||||
|
||||
// type = Condition:
|
||||
condition : Optional<DialogueCondition>
|
||||
trueNodeId : Optional<ID>
|
||||
falseNodeId : Optional<ID>
|
||||
|
||||
// type = Action:
|
||||
action : Optional<DialogueAction>
|
||||
nextNodeId : Optional<ID>
|
||||
}
|
||||
|
||||
DataModel DialogueChoice {
|
||||
choiceText : String
|
||||
nextNodeId : ID
|
||||
availableCondition: Optional<DialogueCondition> // null=始终显示
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 对话条件类型
|
||||
|
||||
```
|
||||
DataModel DialogueCondition {
|
||||
conditionType : DialogueConditionType
|
||||
targetId : Optional<ID>
|
||||
value : Optional<Number>
|
||||
}
|
||||
```
|
||||
|
||||
| 条件类型 | 说明 |
|
||||
|---------|------|
|
||||
| `HasAbility` | 玩家已解锁某能力 |
|
||||
| `HasItem` | 玩家持有某物品 |
|
||||
| `WorldFlagTrue` | 某世界标记为 true |
|
||||
| `QuestStageIs` | 某任务处于指定阶段 |
|
||||
| `BossDefeated` | 某 Boss 已被击败 |
|
||||
| `FirstVisit` | 玩家第一次和此 NPC 对话 |
|
||||
|
||||
### 2.3 对话动作类型
|
||||
|
||||
| 动作类型 | 说明 |
|
||||
|---------|------|
|
||||
| `SetWorldFlag` | 设置世界标记 |
|
||||
| `GiveItem` | 给予物品 |
|
||||
| `GiveGeo` | 给予 Geo |
|
||||
| `UnlockAbility` | 解锁能力 |
|
||||
| `AdvanceQuest` | 推进任务阶段 |
|
||||
| `PlayCutscene` | 播放过场动画 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 世界标记系统
|
||||
|
||||
### 3.1 世界标记规范
|
||||
|
||||
```
|
||||
WorldFlags: Map<String, Boolean>
|
||||
```
|
||||
|
||||
- 存储于 `ProgressionSaveData.worldFlags`
|
||||
- Key 为字符串,建议命名格式:`区域_事件_描述`(如 `region1_boss_firstEncounter`)
|
||||
- 标记只能设为 true,不支持撤销(设计保证单向性)
|
||||
- 叙事系统、门控系统、AI 系统均可读取世界标记
|
||||
|
||||
### 3.2 设置世界标记的来源
|
||||
|
||||
| 来源 | 说明 |
|
||||
|------|------|
|
||||
| 对话动作 `SetWorldFlag` | 对话选择/到达某节点时触发 |
|
||||
| 门控开启 | 某些门控开启时自动设置 |
|
||||
| Boss 死亡 | OnBossDefeated 事件触发时自动设置 |
|
||||
| 收集品拾取 | 特定关键收集品触发 |
|
||||
| 手动触发器 | 场景中的触发区域触碰时 |
|
||||
|
||||
---
|
||||
|
||||
## 4. NPC 状态管理
|
||||
|
||||
### 4.1 NPC 数据模型
|
||||
|
||||
```
|
||||
DataModel NPCData {
|
||||
npcId : ID
|
||||
displayName : String
|
||||
──────────────────────────────────
|
||||
locations : List<NPCLocationEntry> // NPC 在不同阶段的位置
|
||||
dialogueVersions: List<NPCDialogueVersion> // 不同进程阶段的对话
|
||||
}
|
||||
|
||||
DataModel NPCLocationEntry {
|
||||
condition : Optional<DialogueCondition> // 满足时位于此处(null=默认)
|
||||
roomId : ID
|
||||
position : Vector2
|
||||
}
|
||||
|
||||
DataModel NPCDialogueVersion {
|
||||
condition : Optional<DialogueCondition> // 满足时使用此对话(null=默认)
|
||||
dialogueId : ID
|
||||
priority : Integer // 多个条件同时满足时取最高优先级
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 对话版本选取规则
|
||||
|
||||
```
|
||||
玩家与 NPC 交互时:
|
||||
|
||||
枚举 NPCData.dialogueVersions(按 priority 降序)
|
||||
→ 找第一个 condition 满足(或 condition 为 null)的版本
|
||||
→ 使用该版本的 dialogueId 开始对话
|
||||
|
||||
若无任何版本满足 → 使用默认兜底对话("......")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 任务系统
|
||||
|
||||
### 5.1 任务数据模型
|
||||
|
||||
```
|
||||
DataModel QuestData {
|
||||
questId : ID
|
||||
displayName : String
|
||||
description : String
|
||||
──────────────────────────────────
|
||||
stages : List<QuestStageData>
|
||||
rewardOnComplete: Optional<QuestReward>
|
||||
}
|
||||
|
||||
DataModel QuestStageData {
|
||||
stageIndex : Integer
|
||||
description : String
|
||||
completionCondition: DialogueCondition // 推进到下一阶段的条件
|
||||
}
|
||||
|
||||
DataModel QuestReward {
|
||||
geoAmount : Optional<Integer>
|
||||
itemIds : List<ID>
|
||||
abilityId : Optional<ID>
|
||||
worldFlagsToSet : List<String>
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 结局触发系统
|
||||
|
||||
### 6.1 结局条件回顾
|
||||
|
||||
(详细条件见 [09_ProgressionSystem.md](09_ProgressionSystem.md) 第 5 节)
|
||||
|
||||
| 结局 | 类型 | 核心条件 |
|
||||
|------|------|---------|
|
||||
| 结局 A | 普通 | 击败最终 Boss |
|
||||
| 结局 B | 完全 | Boss 全清 + 主线剧情完整 + 关键 NPC 任务 |
|
||||
| 结局 C | 隐藏 | 结局 B + 隐藏世界标记序列激活 |
|
||||
|
||||
### 6.2 结局判定流程
|
||||
|
||||
```
|
||||
最终 Boss 死亡时:
|
||||
|
||||
检查结局 C 条件(最严格)
|
||||
├─ 满足 → 触发结局 C
|
||||
└─ 不满足 →
|
||||
|
||||
检查结局 B 条件
|
||||
├─ 满足 → 触发结局 B
|
||||
└─ 不满足 → 触发结局 A
|
||||
|
||||
触发结局 X:
|
||||
→ 发出 OnEndingTriggered 事件(endingType)
|
||||
→ 播放对应过场动画序列
|
||||
→ 记录到 SaveData(endingUnlocked)
|
||||
→ 游戏结束流程
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 叙事事件目录
|
||||
|
||||
| 事件 | 触发时机 | 载荷 |
|
||||
|------|---------|------|
|
||||
| `OnDialogueStarted` | 开始对话 | `dialogueId, npcId` |
|
||||
| `OnDialogueNodeReached` | 到达对话节点 | `nodeId` |
|
||||
| `OnDialogueChoiceMade` | 玩家做出选择 | `choiceIndex, nextNodeId` |
|
||||
| `OnDialogueEnded` | 对话结束 | `dialogueId` |
|
||||
| `OnWorldFlagSet` | 世界标记变更 | `flagKey` |
|
||||
| `OnQuestStarted` | 任务开始 | `questId` |
|
||||
| `OnQuestAdvanced` | 任务推进 | `questId, newStage` |
|
||||
| `OnQuestCompleted` | 任务完成 | `questId` |
|
||||
| `OnEndingTriggered` | 结局触发 | `endingType` |
|
||||
| `OnCutsceneStarted` | 过场动画开始 | `cutsceneId` |
|
||||
| `OnCutsceneEnded` | 过场动画结束 | `cutsceneId` |
|
||||
Reference in New Issue
Block a user