chore: initial commit

This commit is contained in:
2026-05-08 11:04:00 +08:00
commit f55d2a57c3
6278 changed files with 866081 additions and 0 deletions

View File

@@ -0,0 +1,272 @@
# 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` |