# 01 · 系统架构总览 > **所属文档集** [← 返回索引](./README.md) > **摘要**:定义游戏的核心设计哲学、系统全景图、模块边界与系统间通信规范。 --- ## 目录 1. [设计哲学](#1-设计哲学) 2. [系统全景图](#2-系统全景图) 3. [系统分层模型](#3-系统分层模型) 4. [通信模式规范](#4-通信模式规范) 5. [数据层与逻辑层分离](#5-数据层与逻辑层分离) 6. [模块边界原则](#6-模块边界原则) 7. [系统优先级与生命周期](#7-系统优先级与生命周期) --- ## 1. 设计哲学 ### 1.1 四大核心原则 | 原则 | 含义 | 实践方式 | |------|------|---------| | **零耦合** | 系统间不持有彼此的直接引用 | 通过事件频道或统一接口通信 | | **数据驱动** | 行为由配置数据决定,而非硬编码 | 参数外置为可配置数据模型 | | **行为契约** | 系统对外只暴露接口,不暴露实现 | 所有跨系统调用通过接口进行 | | **单一职责** | 每个系统只负责一件事 | 系统边界清晰,不兼管相邻职责 | ### 1.2 设计动词 理解游戏整体架构的关键词汇: - **探索**:玩家自由穿越相互连接的房间,逐渐解锁新区域 - **弹反**:高风险高回报的格挡反击,是核心战斗循环的差异化机制 - **形态切换**:三种形态提供不同战斗风格,玩家选择适合当前情况的形态 - **资源循环**:灵力(攻击积累)→ 技能消耗 → 再攻击积累,形成持续循环 --- ## 2. 系统全景图 ``` ┌─────────────────────────────────────────────────────────────────────┐ │ 输入层(Input Layer) │ │ 处理原始输入 → 转化为游戏动作事件 → 缓冲管理 │ └──────────────────────────────┬──────────────────────────────────────┘ │ 输入动作事件 ┌──────────────────────────────▼──────────────────────────────────────┐ │ 玩家层(Player Layer) │ │ ┌──────────────┐ ┌─────────────┐ ┌─────────────┐ ┌──────────┐ │ │ │ 移动系统 │ │ 战斗系统 │ │ 形态系统 │ │ 资源系统 │ │ │ │(Movement) │ │ (Combat) │ │ (Form) │ │(Resource)│ │ │ └──────────────┘ └─────────────┘ └─────────────┘ └──────────┘ │ └──────────────────────────────┬──────────────────────────────────────┘ │ 玩家状态事件 ┌──────────────────────────────▼──────────────────────────────────────┐ │ 世界层(World Layer) │ │ ┌──────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 敌人系统 │ │ 世界系统 │ │ 进程系统 │ │ │ │ (Enemy) │ │ (World) │ │(Progression)│ │ │ └──────────────┘ └─────────────┘ └─────────────┘ │ └──────────────────────────────┬──────────────────────────────────────┘ │ 世界状态事件 ┌──────────────────────────────▼──────────────────────────────────────┐ │ 支撑层(Support Layer) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ UI 系统 │ │ 音频系统 │ │ 存档系统 │ │ 叙事系统 │ │ │ │ (UI) │ │ (Audio) │ │ (Save) │ │(Narrative│ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ ┌──────────┐ ┌──────────┐ │ │ │ 经济系统 │ │ 反馈系统 │ │ │ │(Economy) │ │(Feedback)│ │ │ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────────────────┘ ``` --- ## 3. 系统分层模型 ### 层级定义 | 层级 | 名称 | 职责 | 依赖方向 | |------|------|------|---------| | L0 | **配置层** | 只读的设计数据(参数表、模板)| 被所有层引用,不依赖任何层 | | L1 | **输入层** | 原始输入 → 标准化动作事件 | 依赖 L0 | | L2 | **玩家层** | 玩家实体的所有行为 | 依赖 L0, L1 | | L3 | **世界层** | 敌人、关卡、进程 | 依赖 L0, L2(通过接口)| | L4 | **支撑层** | UI、音频、存档、叙事 | 订阅 L2, L3 的事件 | > **设计决策**:高层系统(L4)只通过事件订阅低层系统(L2、L3),不直接调用。 > **原因**:UI 系统永远不应"告诉"玩家系统去做什么,只需观察状态变化后更新显示。 --- ## 4. 通信模式规范 系统间通信允许三种方式,按优先级排序: ### 4.1 事件频道(优先使用) ``` 发出方 接收方 ──────── ──────── 系统 A 系统 B └─ 发出 Event └─ 订阅 Event └─ 执行响应逻辑 ``` **规则**: - 发出方不知道谁在监听 - 接收方不知道谁发出了事件 - 事件只传递"发生了什么",不传递"如何处理"的指令 - 单次事件(One-shot),不轮询 ### 4.2 接口调用(功能依赖) ``` 调用方 被调用方 ──────── ──────── 系统 A 实现了 IInterface 的系统 B └─ 持有 IInterface 引用 └─ 提供 IInterface 实现 └─ 调用 IInterface.Method() ``` **规则**: - 调用方只知道接口,不知道实现 - 接口定义在公共层,不属于任何具体系统 - 允许同步调用并获取返回值 ### 4.3 共享数据读取(只读访问) ``` 消费方 数据源 ──────── ──────── 系统 A 配置数据 / 运行时状态数据 └─ 只读访问共享数据 └─ 数据由其所有者系统维护 ``` **规则**: - 消费方只读,不写 - 写入权唯一归属于数据的所有系统 - 其他系统通过事件订阅感知数据变化,不轮询 ### 4.4 禁止的通信方式 | 禁止模式 | 原因 | |----------|------| | 系统 A 直接持有系统 B 的具体引用 | 产生双向耦合,修改 B 影响 A | | 系统 A 轮询系统 B 的状态 | 性能浪费,职责不清 | | 事件携带"命令"语义("去做 X")| 事件只通知,不指令 | | 支撑层系统调用玩家/世界层方法 | 违反依赖方向,UI 不应控制游戏逻辑 | --- ## 5. 数据层与逻辑层分离 ### 5.1 两类数据 | 类型 | 说明 | 生命周期 | 示例 | |------|------|---------|------| | **配置数据(Config)** | 设计时填写,运行时只读 | 常驻内存 | 移动速度、伤害倍率、关卡布局 | | **运行时状态(State)** | 运行时动态变化 | 随场景/游戏生命周期 | 当前 HP、已解锁能力、世界标志位 | ### 5.2 配置数据模型的设计原则 ``` ConfigData 特征: ✅ 字段全部只读 ✅ 可被多个系统引用(共享) ✅ 可在运行前被工具验证合理性 ✅ 变更不需要修改代码,只修改数据 ❌ 不包含运行时可变字段 ❌ 不包含对具体系统的引用 ``` ### 5.3 运行时状态的所有权 每份运行时状态只有**一个系统**拥有写权限: | 状态 | 所有系统 | 其他系统访问方式 | |------|---------|----------------| | 玩家 HP | 玩家系统 | 事件订阅 `OnHPChanged` | | 世界标志位 | 叙事系统 / 世界系统 | 只读接口查询 | | 背包道具 | 进程系统 | 只读接口查询 | | 货币余额 | 经济系统 | 事件订阅 `OnGeoChanged` | --- ## 6. 模块边界原则 ### 6.1 边界定义规则 系统的边界由以下三要素确定: 1. **输入**:系统响应的事件 + 调用的接口 2. **输出**:系统发出的事件 + 对外提供的接口 3. **状态**:系统独占写权限的运行时数据 ### 6.2 系统边界一览 | 系统 | 输入来源 | 输出目标 | 独占状态 | |------|---------|---------|---------| | 输入系统 | 设备原始信号 | 动作事件(发出)| — | | 玩家系统 | 输入动作事件 | 玩家状态事件 | HP、灵力、魄元、灵泉、Geo、能力 | | 战斗系统 | 碰撞检测结果 | 伤害事件、命中事件 | — | | 敌人系统 | 玩家位置(只读)| 敌人行动事件 | 敌人 HP、AI 状态 | | 世界系统 | 玩家位置(只读)| 场景切换事件 | 房间发现状态、存档点激活状态 | | 进程系统 | 玩家动作事件 | 解锁事件 | 已解锁能力、完成度 | | 存档系统 | 存档/读档请求 | — | 持久化数据快照 | | UI 系统 | 全部状态事件(订阅)| 输入事件(菜单操作)| UI 层堆叠状态 | | 音频系统 | 全部状态事件(订阅)| — | 当前音乐状态 | | 经济系统 | 购买/掉落事件 | 货币变化事件 | Geo 余额 | | 叙事系统 | 世界/玩家事件 | 对话事件、结局评估 | 世界标志位 | --- ## 7. 系统优先级与生命周期 ### 7.1 启动顺序 系统初始化应遵循依赖顺序,低层先于高层初始化: ``` 1. 存档系统(读取持久化数据) 2. 配置数据加载(所有 Config 可用) 3. 输入系统 4. 玩家系统(使用配置和存档数据初始化) 5. 世界系统(加载场景数据) 6. 敌人系统(使用世界数据初始化) 7. 支撑层系统(UI、音频、叙事等) ``` ### 7.2 关卡切换时的系统行为 | 事件 | 各系统行为 | |------|----------| | 触发场景切换 | 世界系统发出 `OnSceneTransitionBegin` | | 过渡动画播放 | UI 系统显示过渡遮罩;输入系统暂停接收 | | 旧场景卸载 | 敌人系统、VFX 等局部系统销毁 | | 新场景加载 | 世界系统重建房间;敌人系统重新初始化 | | 玩家状态恢复 | 玩家系统将 HP/技能应用至新场景(不重置)| | 切换完成 | 世界系统发出 `OnSceneTransitionEnd`;输入系统恢复 | ### 7.3 死亡与复活流程 ``` 玩家 HP 降至 0 → 玩家系统发出 OnPlayerDied → 输入系统:禁止所有输入 → UI 系统:播放死亡遮罩动画 → 音频系统:切换至死亡音乐 → 存档系统:记录死亡位置(遗骸数据) → 世界系统:在上次死亡位置生成遗骸实体 等待(玩家按键或自动)→ 触发复活 复活流程: → 世界系统:加载最近存档点所在场景 → 玩家系统:恢复存档时的 HP / 灵泉次数(见存档规范) → 输入系统:恢复输入 → UI 系统:淡出遮罩 → 音频系统:恢复区域音乐 ``` --- ## 附:常见架构陷阱与规避方法 | 陷阱 | 典型表现 | 规避方法 | |------|---------|---------| | **上帝对象** | 一个系统知道所有其他系统的状态 | 拆分为多个专责系统 | | **循环依赖** | A 依赖 B,B 依赖 A | 引入事件频道或接口打断循环 | | **隐式顺序耦合** | 系统 A 必须在 B 之后执行才正确 | 改用事件触发替代时序依赖 | | **状态同步噩梦** | 多个系统各自维护同一份数据的副本 | 确立唯一所有者,其他系统订阅变化 | | **胖配置数据** | 配置数据里混入运行时逻辑 | 严格区分 Config 和 RuntimeState |