Files
zeling_v2/Docs/DesignSpec/08_WorldSystem.md
2026-05-08 11:04:00 +08:00

273 lines
8.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 08 · 世界系统规范
> **所属文档集** [← 返回索引](./README.md)
> **摘要**:地图结构、房间系统、场景切换管线、存档点与可交互物。
---
## 目录
1. [世界结构层级](#1-世界结构层级)
2. [世界数据模型](#2-世界数据模型)
3. [场景切换管线](#3-场景切换管线)
4. [存档点系统](#4-存档点系统)
5. [可交互物规范](#5-可交互物规范)
6. [收集品系统](#6-收集品系统)
7. [世界状态事件目录](#7-世界状态事件目录)
---
## 1. 世界结构层级
```
World全局
└── Region区域如 废墟之都 / 灵泉洞窟)
└── Zone地区区域内的子区域
└── Room房间最小加载单元
└── Sector区块房间内的逻辑分区
```
| 层级 | 说明 | 数量(预期)|
|------|------|-----------|
| World | 整个游戏世界 | 1 |
| Region | 玩家感知的"大区",通常有独特视觉主题 | 5-8 |
| Zone | Region 内的子区域,对玩家透明(内部分组)| 20-30 |
| Room | 场景加载单元,对应单个可加载场景文件 | 100-200 |
---
## 2. 世界数据模型
### 2.1 地区Region数据
```
DataModel RegionData {
regionId : ID
displayName : String
description : String
──────────────────────────────────
ambientAudioId : AudioID // 区域环境音乐
visualTheme : Ref<VisualThemeData> // 色调/视觉风格
──────────────────────────────────
rooms : List<Ref<RoomData>> // 该区域包含的所有房间
connections : List<RegionConnection> // 与其他区域的连接
}
```
### 2.2 房间Room数据
```
DataModel RoomData {
roomId : ID
regionId : ID // 归属区域
──────────────────────────────────
sceneAssetId : ID // 场景资源引用
spawnPoints : Map<String, Vector2> // 命名生成点(对应门/入口的落地位置)
──────────────────────────────────
connections : List<RoomConnection> // 与其他房间的连接(门/通道)
hasBoss : Boolean
bossId : Optional<ID>
──────────────────────────────────
discoverable : Boolean // 是否出现在地图上
mapGridPos : Vector2 // 在地图 UI 中的格位置
}
```
### 2.3 房间连接模型
```
DataModel RoomConnection {
fromRoomId : ID
fromDoorId : String // 本房间出口标识
toRoomId : ID
toDoorId : String // 目标房间入口标识
──────────────────────────────────
direction : ConnectionDirection // 上/下/左/右
gateId : Optional<ID> // 门控null=无门限制)
}
```
---
## 3. 场景切换管线
### 3.1 切换触发条件
玩家进入出口触发器Exit Trigger触发场景切换流程
```
玩家进入 ExitTrigger
→ 读取 RoomConnection目标房间、目标入口
→ 检查门控条件(若有 gateId
├─ 未满足 → 门保持关闭,播放提示
└─ 满足 → 继续流程
→ 发出 OnRoomTransitionBegin 事件
→ 播放转场动画(淡出、卷帘等)
→ 保存当前房间的必要运行时状态(敌人死亡/开关/收集品)
→ 异步加载目标场景
→ 等待加载完成
→ 将玩家生成到目标房间的指定 spawnPoint
→ 播放转场进入动画
→ 发出 OnRoomTransitionComplete 事件roomId
```
### 3.2 玩家状态保留
| 状态 | 切换时处理 |
|------|-----------|
| HP | 保留(不恢复)|
| 灵力 | 保留 |
| 魄元 | 保留 |
| 灵泉 | 保留 |
| 当前形态 | 保留 |
| Geo | 保留 |
| 无敌帧 | 清除 |
| 速度/冲量 | 清除(生成时重置)|
### 3.3 房间状态持久化
| 状态类型 | 持久化条件 |
|---------|----------|
| 敌人死亡 | 永久(本局游戏内)|
| 开关/机关激活 | 按道具/进程判断(大多数永久)|
| 收集品拾取 | 永久 |
| Boss 死亡 | 永久,切换不重置 |
| 普通敌人死亡 | 重新进入房间后刷新 |
---
## 4. 存档点系统
### 4.1 存档点数据模型
```
DataModel BonfireData {
bonfireId : ID
roomId : ID
position : Vector2
──────────────────────────────────
displayName : String
isActivated : Boolean // 运行时状态,存入 SaveData
fastTravelEnabled: Boolean // 是否支持快速旅行
}
```
### 4.2 激活流程
```
玩家靠近存档点 → 显示交互提示
玩家按下交互键:
若未激活:
→ 播放激活动画
→ 设置 BonfireData.isActivated = true
→ 解锁快速旅行列表中该存档点
激活后(每次交互):
→ 恢复玩家 HP 至最大值
→ 恢复灵泉
→ 重置敌人刷新状态(普通敌人复活)
→ 保存游戏进度到 SaveData
→ 发出 OnBonfireRested 事件
```
> **设计决策**:存档点恢复灵泉
> **原因**:灵泉是 HP 恢复资源,应随存档点恢复;但死亡后不恢复灵泉,强化死亡惩罚
### 4.3 死亡重生规则
- 死亡时:玩家重生于**最后一次使用的存档点**
- 重生时HP 恢复至最大值,**灵泉不恢复**
- 玩家持有的 Geo 遗留在死亡位置(遗骸机制,见 [进程系统](09_ProgressionSystem.md)
---
## 5. 可交互物规范
### 5.1 交互契约
```
Interface IInteractable {
canInteract(player: IPlayerEntity) → Boolean
onInteract(player: IPlayerEntity) → Void
getPromptText() → String
}
```
所有可交互物实现此接口,由玩家系统负责检测并调用。
### 5.2 标准交互物类型
| 类型 | 触发条件 | 行为 |
|------|---------|------|
| 存档点Bonfire| 玩家靠近 + 按交互键 | 激活 / 休息 |
| NPC | 玩家靠近 + 按交互键 | 开始对话(见叙事系统)|
| 商店Vendor| 玩家靠近 + 按交互键 | 打开商店 UI |
| 门Gate| 玩家靠近,满足条件自动开启 | 开启动画 + 移除碰撞 |
| 传送门Portal| 玩家触碰 | 传送到目标地点 |
| 机关Mechanism| 玩家靠近 + 按交互键 | 激活关联机关(开门/升降台)|
| 收集品Collectible| 玩家触碰 / 按键 | 拾取(见收集品系统)|
---
## 6. 收集品系统
### 6.1 收集品数据模型
```
DataModel CollectibleData {
collectibleId : ID
collectibleType : CollectibleType // 见下表
roomId : ID // 所在房间
──────────────────────────────────
displayName : String
description : String
──────────────────────────────────
pickupEffect : PickupEffectType // 拾取时发生什么
pickupParams : Map<String, Number>
}
```
### 6.2 收集品类型
| 类型 | 说明 | 效果 |
|------|------|------|
| `MaxHPUp` | 生命上限增加 | `maxHP += pickupParams["amount"]` |
| `MaxSoulUp` | 灵力上限增加 | `maxSoul += pickupParams["amount"]` |
| `MaxSpiritUp` | 魄元上限增加 | `maxSpirit += pickupParams["amount"]` |
| `AbilityUnlock` | 解锁新能力 | 发出 `OnAbilityUnlocked` 事件 |
| `MapFragment` | 解锁区域地图 | 揭示对应区域地图 |
| `Lore` | 世界观文本 | 加入图鉴/日志 |
| `GeoCache` | 货币缓存 | 立即给予 Geo |
### 6.3 拾取流程
```
玩家触碰 CollectibleEntity
→ 检查 SaveData 该 collectibleId 是否已拾取
├─ 已拾取 → 忽略(不重复拾取)
└─ 未拾取 →
→ 播放拾取动画/音效
→ 执行 pickupEffect更新玩家数据
→ 将 collectibleId 标记为已拾取(写入 SaveData
→ 发出 OnCollectiblePickedUp 事件
→ 销毁实体(本局不再出现)
```
---
## 7. 世界状态事件目录
| 事件 | 触发时机 | 载荷 |
|------|---------|------|
| `OnRoomTransitionBegin` | 场景切换开始 | `fromRoomId, toRoomId` |
| `OnRoomTransitionComplete` | 场景切换完成 | `roomId` |
| `OnRoomFirstVisit` | 首次进入某房间 | `roomId` |
| `OnBonfireActivated` | 首次激活存档点 | `bonfireId` |
| `OnBonfireRested` | 使用存档点休息 | `bonfireId` |
| `OnCollectiblePickedUp` | 拾取收集品 | `collectibleId, collectibleType` |
| `OnGateOpened` | 门控解锁 | `gateId, roomId` |
| `OnBossRoomEntered` | 进入 Boss 房间 | `roomId, bossId` |
| `OnBossDefeated` | Boss 死亡 | `bossId` |