131 lines
8.3 KiB
Markdown
131 lines
8.3 KiB
Markdown
# 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>
|