Files
erqiwang_youle/docs/client/development-guide/05-开发规范与红线.md
T
2026-07-06 17:16:05 +08:00

9.0 KiB
Raw Blame History

05 · 开发规范与红线

本篇汇总前端必须遵守的工程纪律,是代码审查清单的来源。改任何代码前按相关条目自检。前面 01–04 是“怎么做”,本篇是“不许怎么做 / 必须怎么做”。


1. 可编辑范围

区域 可改性
js/vendor/、js/00_Surface/ 禁改(第三方/平台代码)
01_SubGame/00_SubGame_Config.js 仅可改值:只给已有 Game_Config.* 配置项赋值;禁止新增/删除/改名/改结构定义(三文件中唯一子游戏可碰者,且仅限改值)。详见 06
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. 数据权威、组件数据与表现延后

  • 服务端权威:所有核心运算与胜负裁定以服务端为准、数据以服务端为权威;前端只做界面展示与玩家交互,本地数据仅为「渲染副本」,不做权威计算。
  • 组件数据自持 + set-refresh:组件(及其下每个「零件 UI」)的自有数据集中在 this.data,不散落各处;每个 UI 都有 setXxx(只写数据)/refreshXxx(只据数据画界面)成对方法,组件另有总 refresh() 据 this.data 重建整块界面(见 02)。
  • 收包节奏:先 setXxx 写数据 →(必要时 refresh 刷静态界面)→ 再播动画 → 动画回调里只刷新界面;动画的开始/结束/出错等生命周期回调里绝不设置核心数据,动画期间不改数据。
  • 重画随时可用:任何时候调 refresh 都能据 this.data 重建正确界面(网页刷新/断线重连/切 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)。详见服务端 04 §8 shared 文件同步流程。

9. 模块职责边界

  • 一个职能只在一个模块实现,其他模块调用而非重造:渲染找 SpriteManager、动画找 AnimationManager(及游戏动画封装)、音频找游戏音频管理、Spine 找 SpineMgr(及 Spine 回调分发)、发包找语义化发包封装、收包分发找收包分发器。
  • 写代码前先问“这段属于谁的职责”,属于别人就调用它,不在本模块复制一份近似实现。

10. 测试纪律

  • 测试用于验证业务正确性;失败先裁定根因归属(业务缺陷 vs 测试脚本缺陷),禁止 skip/软化断言/吞异常掩盖。
  • 业务缺陷修业务并单独提交;脚本缺陷修置场并保持硬断言。
  • shared/ 算法变更应在 Node 跑相应单测验证(前后端同源)。

11. 审查速查表

维度 红线
范围 vendor/00_Surface 禁改;受限文件不新增接口;shared 只读
语言 严格 ES5;新文件插对加载顺序
框架中立 框架无玩法逻辑/专属常量;专属内容归子游戏
渲染 只走 SpriteManager;ID 守范围、不编造;查返回值
常量 精灵/资源/坐标/动画/音效/事件全集中,禁硬编码裸值
组件 继承 BaseComponent;事件 addEventListener;destroy 清动态精灵/定时器
数据 服务端权威(核心运算/裁定在服务端);组件自有数据集中 this.data;每个 UI/零件有 set/refresh 对、组件有总 refresh
节奏 先写数据后表现;动画回调只刷界面、不写核心数据;重画可随时据数据还原界面
成败 只认 data.success,禁 status 兜底
收发包 发走语义化发包封装、收走收包分发器;业务不进 Game_Modify
职责 一职能一模块,调用不重造

至此 01–05 构成一套完整的前端子游戏开发指导。回到 README 查看导航与分层模型。