# 00 · 设计规范与符号约定 > **所属文档集** [← 返回索引](./README.md) > **用途**:阅读本文档集前的必读指南,定义所有文档统一使用的符号、术语和格式约定。 --- ## 目录 1. [文档定位原则](#1-文档定位原则) 2. [抽象数据类型](#2-抽象数据类型) 3. [数据模型符号](#3-数据模型符号) 4. [接口契约符号](#4-接口契约符号) 5. [状态机符号](#5-状态机符号) 6. [事件符号](#6-事件符号) 7. [系统依赖符号](#7-系统依赖符号) 8. [参数表格式](#8-参数表格式) 9. [设计决策标注](#9-设计决策标注) --- ## 1. 文档定位原则 ### 1.1 本文档集的边界 | ✅ 应包含 | ❌ 不应包含 | |----------|-----------| | 系统的功能目标(做什么)| 特定引擎的组件名称(MonoBehaviour、Node 等)| | 数据模型与字段语义 | 特定语言的代码语法 | | 系统间的通信契约 | 特定插件/库的调用方式 | | 状态机的状态与转换规则 | 文件系统路径、资产命名规范 | | 行为触发的条件与结果 | 引擎内部执行顺序(Update、FixedUpdate)| | 配置参数的含义与推荐范围 | Inspector 字段序列化细节 | | 设计决策的原因(Why)| 代码模块的命名空间划分 | ### 1.2 阅读层次 ``` 本文档集(DesignSpec) ↓ 解释"做什么、为什么" Docs/Architecture(引擎架构文档) ↓ 解释"代码如何组织、各模块如何实现" 实际代码 ↓ 最终实现 ``` --- ## 2. 抽象数据类型 本文档集使用以下引擎无关的抽象类型: | 符号 | 含义 | 示例 | |------|------|------| | `Integer` | 整数 | `hp: Integer` | | `Number` | 浮点数 | `speed: Number` | | `Boolean` | 布尔值 | `isGrounded: Boolean` | | `String` | 字符串 | `id: String` | | `ID` | 唯一标识符(字符串或枚举)| `formId: ID` | | `List` | 有序列表 | `skills: List` | | `Map` | 键值映射 | `flagMap: Map` | | `Optional` | 可为空的值 | `target: Optional` | | `Ref` | 对另一数据模型的引用 | `weapon: Ref` | | `Enum` | 枚举类型(正文中明确列出所有值)| `DamageType` | | `Flags` | 可组合的位标记集 | `DamageFlags` | | `Duration` | 时间长度(秒)| `stunDuration: Duration` | | `Vector2` | 二维方向或坐标 | `knockbackDir: Vector2` | --- ## 3. 数据模型符号 数据模型描述一组字段的结构,**不含逻辑**,类似数据表或结构体: ``` DataModel ModelName { fieldName : Type // 字段说明 fieldName : Type = default // 带默认值 fieldName : Optional // 可选字段 ──────────────────────────────── // 分隔线表示分组 groupedField : Type // 同组字段 } ``` ### 示例 ``` DataModel DamagePacket { rawDamage : Integer // 基础伤害 damageType : DamageType // 伤害类型枚举 knockbackDir : Vector2 // 击退方向(单位向量) knockbackForce : Number // 击退力度 stunDuration : Duration // 硬直时长(秒) flags : Flags ────────────────────────────────── sourceId : ID // 攻击来源的唯一标识(用于特殊规则查询) sourcePosition : Vector2 // 攻击来源位置(计算击退方向时备用) } ``` --- ## 4. 接口契约符号 接口描述一个系统对外暴露的操作与属性,不规定内部实现: ``` Interface IInterfaceName { // 只读属性 [readonly] propertyName : Type // 可写属性 [readwrite] propertyName : Type // 方法:方法名(参数名: 类型, …) → 返回类型 // 若无返回值写 void methodName(param: Type) → ReturnType // 可失败的方法(返回 Result) methodName(param: Type) → Result // 事件(外部可订阅) [event] onSomething : EventType } ``` ### 示例 ``` Interface IHealthOwner { [readonly] currentHP : Integer [readonly] maxHP : Integer [readonly] isAlive : Boolean takeDamage(packet: DamagePacket) → void heal(amount: Integer) → void [event] onHPChanged : Event [event] onDied : Event } ``` --- ## 5. 状态机符号 ### 5.1 状态定义 ``` State StateName { priority : Integer // 数字越大、越难被低优先级状态打断 interruptBy: List // 可被哪些状态强制打断 } ``` ### 5.2 状态转换图 ``` [StateA] ──条件──► [StateB] // 正常转换 ══强制══► [StateC] // 强制(忽略优先级) ~~超时~~► [StateD] // 超时自动转换 [StateB] ──落地────────────► [IdleState] ──攻击输入─────────► [AttackState] ``` ### 5.3 转换条件格式 | 符号 | 含义 | |------|------| | `──条件──►` | 满足条件后转换 | | `══强制══►` | 外部强制调用,跳过优先级检查 | | `~~超时~~►` | 经过 N 秒后自动转换 | | `[condition AND condition]` | 复合条件 | | `[NOT condition]` | 条件取反 | --- ## 6. 事件符号 事件用于系统间的解耦通知,只传递最小必要数据: ``` Event EventName { payload: PayloadType // 携带的数据,void 表示无数据 emitter: SystemName // 哪个系统发出 listeners: [SystemA, SystemB, ...] // 典型订阅方(非强制) } ``` ### 事件目录格式 | 事件名 | 载荷类型 | 发出方 | 用途 | |--------|---------|--------|------| | `OnPlayerDied` | `void` | 玩家系统 | 触发复活流程 | | `OnHPChanged` | `{current, max}` | 玩家系统 | 更新 HUD | --- ## 7. 系统依赖符号 系统之间的依赖关系通过以下格式表达: ``` SystemA ──读取──► DataModel // 读取数据 SystemA ──写入──► DataModel // 写入数据 SystemA ──发出──► EventX // 发出事件 SystemA ◄─订阅── EventY // 订阅事件 SystemA ──调用──► IInterface // 调用接口方法 系统间不应出现: SystemA ──直接引用──► SystemB // ❌ 禁止直接持有另一系统引用 ``` ### 依赖等级 | 等级 | 说明 | |------|------| | **强依赖**(编译时)| A 的存在必须依赖 B 的接口定义 | | **弱依赖**(运行时事件)| A 通过事件通知 B,B 不存在时 A 仍可正常运行 | | **数据依赖**(只读配置)| A 读取共享配置数据,无运行时交互 | --- ## 8. 参数表格式 配置参数表统一格式: | 参数名 | 类型 | 推荐值 | 说明 | 调整影响 | |--------|------|--------|------|---------| | `walkSpeed` | Number | 6.0 | 地面行走速度(单位/秒)| 越高越灵活,越低越沉重 | | `jumpForce` | Number | 16.0 | 跳跃初速度 | 越高跳跃越高,需同步调整重力 | > **调整原则**:每次只修改一个参数,实测手感后确认。参数间存在联动关系时,文档中注明。 --- ## 9. 设计决策标注 文档中的设计决策用以下格式标注原因,方便日后回溯: ``` > **设计决策**:[决策内容] > **原因**:[为什么这样设计] > **替代方案**:[考虑过但未选用的方案及原因] ``` ### 示例 > **设计决策**:弹反成功后增加 +33 灵力,而非固定值 > **原因**:鼓励玩家主动弹反,弹反本身是高风险操作,大幅奖励使弹反策略具有可行的资源通路 > **替代方案**:弹反+0 灵力(纯战斗技巧),但测试发现玩家没有足够动机学习弹反 --- ## 附:文档写作检查清单 在向本文档集新增或修改文档时,请确认: - [ ] 所有数据类型使用抽象类型(不出现 `int`, `float`, `string`, `MonoBehaviour` 等) - [ ] 所有引擎功能通过行为描述替代("物理检测地面"而非"OverlapBox") - [ ] 系统接口以契约格式定义,不包含实现细节 - [ ] 参数表包含"调整影响"列 - [ ] 重要设计决策附有原因说明 - [ ] 文档末尾无悬空的"TODO"或临时注记