Files
erqiwang_youle/docs/client/development-guide/05-开发规范与红线.md
T

131 lines
8.3 KiB
Markdown
Raw 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.
# 05 · 开发规范与红线
本篇汇总前端**必须遵守**的工程纪律,是代码审查清单的来源。改任何代码前按相关条目自检。前面 01–04 是“怎么做”,本篇是“不许怎么做 / 必须怎么做”。
---
## 1. 可编辑范围
| 区域 | 可改性 |
|------|--------|
| `js/vendor/`、`js/00_Surface/` | **禁改**(第三方/平台代码) |
| `01_SubGame/00_SubGame_Config.js` | **仅可改值**:只给**已有** `Game_Config.*` 配置项赋值;**禁止**新增/删除/改名/改结构定义(三文件中唯一子游戏可碰者,且仅限改值)。详见 [06](./06-子游戏接入模式与Hooks外置.md) |
| `01_SubGame/01_SubGame_modify.js` | **受限**:仅顶部「配置区」填值(`Type_*/CreateRoomData/combat/game_config/roomDes`);转发壳/平台接口**不碰、不新增**,业务走子游戏实现层。详见 06 |
| `01_SubGame/02_SubGame_Input.js` | **不碰**:框架维护的平台接口骨架/转发壳,不改、不新增接口、不写业务。详见 06 |
| `js/gameabc-framework/` | 可改,但须保持**游戏中立**(见 §3) |
| `01_SubGame/codes/`(除 `shared/`) | 子游戏自由开发区 |
| `01_SubGame/codes/shared/` | **只读**:服务端 `shared/` 的同步副本,改服务端权威源再同步(见 §7) |
新增前后端交互一律走服务端 `mod.js` 的 `rpc` 机制 + 前端统一发包/收包封装,**不在受限文件新增接口**。
---
## 2. 语言标准:严格 ES5
- 用 `var`/`function`;对象继承用 `Object.create(Base)` + 在 `init` 内重声明实例属性。
- **禁** `let`/`const`、箭头函数、模板字符串、解构、默认参数、展开、`class`、`for...of`。
- 跨文件按**全局名**引用(各文件 `var X = ...` 暴露全局,`index.html` 顺序加载);新增文件必须在 `index.html` 插到依赖之后、使用者之前。
---
## 3. 框架游戏中立
`gameabc-framework/` 是给**任意子游戏**复用的通用框架,**不得**渗入任何具体玩法:
- **禁止**在框架内出现玩法逻辑、玩法专属常量(牌型、动作、玩法事件名等)。
- 玩法专属内容一律定义在**子游戏侧**:
- 玩法事件 → 子游戏事件常量文件,追加到 `EventBus.Events`;
- 音效映射 → 子游戏音效资源常量 + 游戏音频管理;
- Spine 动作 → 子游戏 Spine 动作配置;
- 资源/布局 → 子游戏精灵结构/图片资源/布局常量。
- **违例信号**:框架文件里出现 `mahjong:`、牌型、吃碰杠胡等具体玩法字样(注释举例除外,且举例应尽量中立)。
> 范例:本仓库把框架 `EventBus.js` 内**所有**预定义事件常量清空(只留空容器 `EventBus.Events={}`),全部事件(通用语义 + 玩法专属)改由子游戏的事件常量文件定义;并把通用的精灵事件控制器从子游戏抽到框架 `system/SpriteEventController.js`、剥离其中的玩法标记耦合为「全局 draw 钩子」;把 `UIManager` 的全局 UI(Loading/Message/Confirm)从「主动读子游戏精灵常量」改为「由子游戏 `init(config)` 注入」。新玩法照此扩展,框架零改动。
---
## 4. 渲染与常量
- **精灵只走 `SpriteManager`**:UI 代码禁止直接调 `GameABCUtils`/引擎原生 API。
- **ID 守范围**:精灵 1001–3000、群组 ≥201、普通图层 101–200、弹窗图层 301–400(另有 501–600、701+ 备用段);框架保留 1–1000 及 3001+(精灵)等交替段,不可占用;ID 必须与编辑器一致,不编造。
- **检查返回值**:`SpriteManager.*` 返回 `false` 即 ID/范围有误,及时暴露。
- **常量集中、禁硬编码**:精灵 ID / 图片资源 ID / 坐标尺寸 / 动画时长帧数 / 音效 ID / 事件名,一律定义在对应常量文件,业务代码只引用:
- 精灵结构 → 精灵结构常量(主界面/弹窗分文件)
- 图片资源 → 图片资源常量
- 布局坐标 → 布局常量
- 动画参数 → 动画配置
- 音效 ID → 音效资源常量
- 事件名 → `EventBus.Events`(专属在子游戏事件常量文件)
- 整合入口 → 精灵常量整合入口(**最后加载**)
---
## 5. UI 组件生命周期与内存安全
- **组件继承 `BaseComponent`**,在 `init` 内重声明实例属性、建精灵、注册事件。
- **事件用 `this.addEventListener`** 订阅(`destroy()` 自动 `off`),**禁**裸 `EventBus.on`(会泄漏)。
- **销毁用 `destroy()`** 而非只 `hide()`;在 `onDestroy` 清理**定时器、动态复制精灵、Spine 回调登记**。
- 动态列表用 `DynamicSpriteList` 并在销毁时 `list.destroy()`,避免复制精灵残留。
---
## 6. 数据优先、表现延后
- 收到推送的固定节奏:**先改数据模型 → 再播动画 → 动画回调里刷新静态界面**;动画期间**不改数据**。
- **重画函数**据本地数据可随时重建正确界面(如网页刷新);断线重连与切 app 复用同一重画路径,不为重连单写一套渲染。
- 开发阶段可**先不做动画**,只保证静态界面正确;动画作为后续叠加,不影响界面正确性。
---
## 7. 成败标志与收发包
- **成败只认 `data.success`**:`if (!data.success)` 判失败;**禁**用 `status`/`code` 判成败、**禁** `status` 兼容兜底。个别嵌套场景按该推送契约取 `success` 所在字段,语义不变。
- **发包走语义化发包封装/`RpcHelper`**(自动注入平台字段),**收包统一分发**(一 rpc 一处理器)。
- 业务逻辑放 controllers/managers,**不**写进受限 `Game_Modify.*`。
---
## 8. shared 同步
- **`shared/` 是子游戏自己的游戏逻辑,与平台无关**:存放本玩法**前后端必须算出完全一致**的纯逻辑(胡牌/听牌/比精/牌型/计分/规则常量等),前端用于即时表现与预校验,服务端做权威裁定。它不是平台代码,平台既不提供也不感知。
- `01_SubGame/codes/shared/` 是服务端 `server/<游戏容器目录>/<游戏>/shared/` 的**同步副本**,前端**只读**(脚本生成)。
- 改共享算法只改服务端权威源,再运行同步脚本覆盖前端副本;**禁止直接编辑前端 `codes/shared/`**。
- 逻辑同源不改变数据权威:前端 `shared/` 算的是表现/预判,最终以服务端为准(数据优先、表现延后,见 §6)。详见服务端 [`server/docs/development-guide/04 §8`](../../../server/docs/development-guide/04-开发规范与红线.md#8-shared-文件同步流程)。
---
## 9. 模块职责边界
- 一个职能只在一个模块实现,其他模块**调用而非重造**:渲染找 `SpriteManager`、动画找 `AnimationManager`(及游戏动画封装)、音频找游戏音频管理、Spine 找 `SpineMgr`(及 Spine 回调分发)、发包找语义化发包封装、收包分发找收包分发器。
- 写代码前先问“这段属于谁的职责”,属于别人就调用它,不在本模块复制一份近似实现。
---
## 10. 测试纪律
- 测试用于验证业务正确性;失败先**裁定根因归属**(业务缺陷 vs 测试脚本缺陷),禁止 skip/软化断言/吞异常掩盖。
- 业务缺陷修业务并单独提交;脚本缺陷修置场并保持硬断言。
- `shared/` 算法变更应在 Node 跑相应单测验证(前后端同源)。
---
## 11. 审查速查表
| 维度 | 红线 |
|------|------|
| 范围 | `vendor`/`00_Surface` 禁改;受限文件不新增接口;`shared` 只读 |
| 语言 | 严格 ES5;新文件插对加载顺序 |
| 框架中立 | 框架无玩法逻辑/专属常量;专属内容归子游戏 |
| 渲染 | 只走 `SpriteManager`;ID 守范围、不编造;查返回值 |
| 常量 | 精灵/资源/坐标/动画/音效/事件全集中,禁硬编码裸值 |
| 组件 | 继承 `BaseComponent`;事件 `addEventListener`;`destroy` 清动态精灵/定时器 |
| 节奏 | 先数据后表现;重画可随时还原界面 |
| 成败 | 只认 `data.success`,禁 `status` 兜底 |
| 收发包 | 发走语义化发包封装、收走收包分发器;业务不进 `Game_Modify` |
| 职责 | 一职能一模块,调用不重造 |
---
至此,从架构与环境(01)、渲染与组件(02)、表现系统(03)、网络与启动(04)到工程红线(05),构成一套完整的前端子游戏开发指导。回到 [README](./README.md) 查看导航与分层模型。
</content>