文档修复:校正开发指南编号与失效交叉引用
- CLAUDE.md:前端指南编号由「01→05」订正为「01→06」(06 子游戏接入模式实存且已被本文件他处引用);删除已过期的 server/docs 旧副本警告(该旧副本已从工作树删除)。 - 两份 development-guide README + 各章节正文:将旧路径 server/docs/development-guide、client/docs/development-guide 统一订正为 docs/server、docs/client;docs/engineering 订正为 docs/games/engineering。 - 客户端 README 阅读顺序补齐缺失的 06 篇。 - 服务端 README 移除指向不存在的 docs/important/server 的条目。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -87,9 +87,7 @@ server/<游戏容器目录>/<游戏>/ ← 子游戏接入后**唯一
|
|||||||
|
|
||||||
### 文档(改动前先读)
|
### 文档(改动前先读)
|
||||||
|
|
||||||
`docs/client/development-guide/`与`docs/server/development-guide/`(按 01→05/04 编号)是本项目遵循的权威、项目专属开发指南——改哪块就读对应编号的文档,而不是从代码反推约定。`docs/games/engineering/` 是位于两者之上的、与平台无关的工程方法论层(单一权威数据源 SSOT、单向依赖、职责单一、对扩展开放对修改封闭 OCP、配置优先于硬编码、显式失败优于隐式兜底)。
|
`docs/client/development-guide/`(01→06 编号)与`docs/server/development-guide/`(01→04 编号)是本项目遵循的权威、项目专属开发指南——改哪块就读对应编号的文档,而不是从代码反推约定。`docs/games/engineering/` 是位于两者之上的、与平台无关的工程方法论层(单一权威数据源 SSOT、单向依赖、职责单一、对扩展开放对修改封闭 OCP、配置优先于硬编码、显式失败优于隐式兜底)。
|
||||||
|
|
||||||
注意:`server/docs/development-guide/` 是 `docs/server/development-guide/` 的旧版、部分过期的副本(例如它仍写死可编辑目录为 `games2/`,而新版已改为「容器目录名不再框架强制」)。两者冲突时以 `docs/server/development-guide/` 为准。
|
|
||||||
|
|
||||||
具体子游戏「二七王」(`server/games/erqiwang/`)另有两份权威文档,改动该子游戏前必读:
|
具体子游戏「二七王」(`server/games/erqiwang/`)另有两份权威文档,改动该子游戏前必读:
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
本篇讲**前端怎么和服务端打通、一局怎么启动**:发包链路、收包分发、新旧架构的对接边界、成败判定、启动顺序与 controllers/managers 的职责。
|
本篇讲**前端怎么和服务端打通、一局怎么启动**:发包链路、收包分发、新旧架构的对接边界、成败判定、启动顺序与 controllers/managers 的职责。
|
||||||
|
|
||||||
> **想看前后端端到端全链路**(一个包从前端出发 → 服务端三层路由/handler → 推回前端分发的完整往返、及各步在谁的哪个文件)见服务端 [`server/docs/development-guide/03 §6`](../../../server/docs/development-guide/03-数据收发与通信协议.md#6-端到端收发全链路前后端对照)。本篇聚焦**前端这一侧**的收发细节。
|
> **想看前后端端到端全链路**(一个包从前端出发 → 服务端三层路由/handler → 推回前端分发的完整往返、及各步在谁的哪个文件)见服务端 [`docs/server/development-guide/03 §6`](../../server/development-guide/03-数据收发与通信协议.md#6-端到端收发全链路前后端对照)。本篇聚焦**前端这一侧**的收发细节。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ Game_Modify.StartWar = function (_msg) {
|
|||||||
|
|
||||||
## 4. 成败判定:只认 `data.success`
|
## 4. 成败判定:只认 `data.success`
|
||||||
|
|
||||||
> 与服务端 [`server/docs/development-guide/03`](../../../server/docs/development-guide/03-数据收发与通信协议.md) 同一条协议。
|
> 与服务端 [`docs/server/development-guide/03`](../../server/development-guide/03-数据收发与通信协议.md) 同一条协议。
|
||||||
|
|
||||||
前端 RPC 没有“同步返回”,操作结果由服务端**后续主动推送**告知。判成败的唯一权威是推送 `data` 里的 **`success`**:
|
前端 RPC 没有“同步返回”,操作结果由服务端**后续主动推送**告知。判成败的唯一权威是推送 `data` 里的 **`success`**:
|
||||||
|
|
||||||
|
|||||||
@@ -69,11 +69,13 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6. 数据优先、表现延后
|
## 6. 数据权威、组件数据与表现延后
|
||||||
|
|
||||||
- 收到推送的固定节奏:**先改数据模型 → 再播动画 → 动画回调里刷新静态界面**;动画期间**不改数据**。
|
- **服务端权威**:所有核心运算与胜负裁定以服务端为准、数据以服务端为权威;前端只做界面展示与玩家交互,本地数据仅为「渲染副本」,不做权威计算。
|
||||||
- **重画函数**据本地数据可随时重建正确界面(如网页刷新);断线重连与切 app 复用同一重画路径,不为重连单写一套渲染。
|
- **组件数据自持 + set-refresh**:组件(及其下每个「零件 UI」)的自有数据集中在 `this.data`,**不散落**各处;每个 UI 都有 `setXxx`(只写数据)/`refreshXxx`(只据数据画界面)成对方法,组件另有总 `refresh()` 据 `this.data` 重建整块界面(见 02)。
|
||||||
- 开发阶段可**先不做动画**,只保证静态界面正确;动画作为后续叠加,不影响界面正确性。
|
- **收包节奏**:**先 `setXxx` 写数据 →(必要时 `refresh` 刷静态界面)→ 再播动画 → 动画回调里只刷新界面**;动画的开始/结束/出错等生命周期回调里**绝不设置核心数据**,动画期间**不改数据**。
|
||||||
|
- **重画随时可用**:任何时候调 `refresh` 都能据 `this.data` 重建正确界面(网页刷新/断线重连/切 app 复用同一路径,不为重连单写一套渲染)。
|
||||||
|
- **动画是体验层**:开发阶段可**先不做动画**只保证静态界面正确;即使动画缺失/卡住/播错,数据、逻辑与界面仍正确、互不影响。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -90,7 +92,7 @@
|
|||||||
- **`shared/` 是子游戏自己的游戏逻辑,与平台无关**:存放本玩法**前后端必须算出完全一致**的纯逻辑(胡牌/听牌/比精/牌型/计分/规则常量等),前端用于即时表现与预校验,服务端做权威裁定。它不是平台代码,平台既不提供也不感知。
|
- **`shared/` 是子游戏自己的游戏逻辑,与平台无关**:存放本玩法**前后端必须算出完全一致**的纯逻辑(胡牌/听牌/比精/牌型/计分/规则常量等),前端用于即时表现与预校验,服务端做权威裁定。它不是平台代码,平台既不提供也不感知。
|
||||||
- `01_SubGame/codes/shared/` 是服务端 `server/<游戏容器目录>/<游戏>/shared/` 的**同步副本**,前端**只读**(脚本生成)。
|
- `01_SubGame/codes/shared/` 是服务端 `server/<游戏容器目录>/<游戏>/shared/` 的**同步副本**,前端**只读**(脚本生成)。
|
||||||
- 改共享算法只改服务端权威源,再运行同步脚本覆盖前端副本;**禁止直接编辑前端 `codes/shared/`**。
|
- 改共享算法只改服务端权威源,再运行同步脚本覆盖前端副本;**禁止直接编辑前端 `codes/shared/`**。
|
||||||
- 逻辑同源不改变数据权威:前端 `shared/` 算的是表现/预判,最终以服务端为准(数据优先、表现延后,见 §6)。详见服务端 [`server/docs/development-guide/04 §8`](../../../server/docs/development-guide/04-开发规范与红线.md#8-shared-文件同步流程)。
|
- 逻辑同源不改变数据权威:前端 `shared/` 算的是表现/预判,最终以服务端为准(数据优先、表现延后,见 §6)。详见服务端 [`docs/server/development-guide/04 §8`](../../server/development-guide/04-开发规范与红线.md#8-shared-文件同步流程)。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -119,7 +121,8 @@
|
|||||||
| 渲染 | 只走 `SpriteManager`;ID 守范围、不编造;查返回值 |
|
| 渲染 | 只走 `SpriteManager`;ID 守范围、不编造;查返回值 |
|
||||||
| 常量 | 精灵/资源/坐标/动画/音效/事件全集中,禁硬编码裸值 |
|
| 常量 | 精灵/资源/坐标/动画/音效/事件全集中,禁硬编码裸值 |
|
||||||
| 组件 | 继承 `BaseComponent`;事件 `addEventListener`;`destroy` 清动态精灵/定时器 |
|
| 组件 | 继承 `BaseComponent`;事件 `addEventListener`;`destroy` 清动态精灵/定时器 |
|
||||||
| 节奏 | 先数据后表现;重画可随时还原界面 |
|
| 数据 | 服务端权威(核心运算/裁定在服务端);组件自有数据集中 `this.data`;每个 UI/零件有 set/refresh 对、组件有总 `refresh` |
|
||||||
|
| 节奏 | 先写数据后表现;动画回调只刷界面、**不写核心数据**;重画可随时据数据还原界面 |
|
||||||
| 成败 | 只认 `data.success`,禁 `status` 兜底 |
|
| 成败 | 只认 `data.success`,禁 `status` 兜底 |
|
||||||
| 收发包 | 发走语义化发包封装、收走收包分发器;业务不进 `Game_Modify` |
|
| 收发包 | 发走语义化发包封装、收走收包分发器;业务不进 `Game_Modify` |
|
||||||
| 职责 | 一职能一模块,调用不重造 |
|
| 职责 | 一职能一模块,调用不重造 |
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
## 这套文档写给谁
|
## 这套文档写给谁
|
||||||
|
|
||||||
- **新接手子游戏前端的开发者**:先读 01、02 建立全局认知,再按 03、04 动手,05 随时回查。
|
- **新接手子游戏前端的开发者**:先读 01、02 建立全局认知,再按 03、04、06 动手,05 随时回查。
|
||||||
- **正在开发/维护某子游戏前端的开发者**:02–05 是日常手册与红线。
|
- **正在开发/维护某子游戏前端的开发者**:02–06 是日常手册与红线。
|
||||||
- **做代码审查的人**:05 是审查清单来源。
|
- **做代码审查的人**:05 是审查清单来源。
|
||||||
|
|
||||||
## 阅读顺序
|
## 阅读顺序
|
||||||
@@ -20,12 +20,13 @@
|
|||||||
|----|------|--------------|
|
|----|------|--------------|
|
||||||
| 00 | 本文 README | 这套文档是什么、怎么读、红线速查 |
|
| 00 | 本文 README | 这套文档是什么、怎么读、红线速查 |
|
||||||
| 01 | [01-前端架构与运行环境.md](./01-前端架构与运行环境.md) | 双运行时/ES5、平台/框架/子游戏三层、新旧架构并存、目录与加载顺序 |
|
| 01 | [01-前端架构与运行环境.md](./01-前端架构与运行环境.md) | 双运行时/ES5、平台/框架/子游戏三层、新旧架构并存、目录与加载顺序 |
|
||||||
| 02 | [02-渲染与UI组件体系.md](./02-渲染与UI组件体系.md) | 精灵 ID 体系、SpriteManager 分层、资源常量组织、BaseComponent 组件化、UIManager 场景、动态列表 |
|
| 02 | [02-渲染与UI组件体系.md](./02-渲染与UI组件体系.md) | 精灵 ID 体系、SpriteManager 分层、资源常量组织、BaseComponent 组件化、组件数据/set-refresh 范式、UIManager 场景、动态列表 |
|
||||||
| 03 | [03-事件·动画·音频·Spine.md](./03-事件·动画·音频·Spine.md) | EventBus、AnimationManager+配置、AudioManager+音效资源、SpineMgr 全链路 |
|
| 03 | [03-事件·动画·音频·Spine.md](./03-事件·动画·音频·Spine.md) | EventBus、AnimationManager+配置、AudioManager+音效资源、SpineMgr 全链路 |
|
||||||
| 04 | [04-网络对接与启动编排.md](./04-网络对接与启动编排.md) | 发包链路(RpcHelper 注入平台字段)、收包统一分发、新旧架构对接边界、启动编排、处理器/管理器职责 |
|
| 04 | [04-网络对接与启动编排.md](./04-网络对接与启动编排.md) | 发包链路(RpcHelper 注入平台字段)、收包统一分发、新旧架构对接边界、启动编排、处理器/管理器职责 |
|
||||||
| 05 | [05-开发规范与红线.md](./05-开发规范与红线.md) | 可编辑范围、ES5、框架中立、常量集中、组件生命周期、data.success、模块职责、测试 |
|
| 05 | [05-开发规范与红线.md](./05-开发规范与红线.md) | 可编辑范围、ES5、框架中立、常量集中、组件生命周期、服务端权威/组件数据/表现延后、data.success、模块职责、测试 |
|
||||||
|
| 06 | [06-子游戏接入模式与Hooks外置.md](./06-子游戏接入模式与Hooks外置.md) | 内联模式 vs Hooks 外置模式、三个契约文件退化为转发壳、SubGameHooks 委托、subgame-entry 模板 |
|
||||||
|
|
||||||
建议第一次**从 01 顺序读到 05**;之后把 02–05 当手册随用随查。
|
建议第一次**从 01 顺序读到 06**;之后把 02–06 当手册随用随查。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -60,8 +61,10 @@ BaseComponent / UIManager(ui,组件化与场景) ← gameabc-framework(
|
|||||||
- **框架游戏中立**:`gameabc-framework/` 内**不得**出现任何具体玩法逻辑或专属常量;玩法专属的事件/资源/配置一律定义在子游戏侧(如玩法事件在子游戏的事件常量文件里追加到 `EventBus.Events`)。
|
- **框架游戏中立**:`gameabc-framework/` 内**不得**出现任何具体玩法逻辑或专属常量;玩法专属的事件/资源/配置一律定义在子游戏侧(如玩法事件在子游戏的事件常量文件里追加到 `EventBus.Events`)。
|
||||||
- **精灵只走 SpriteManager**:UI 代码**禁止**直接调 `GameABCUtils` 或引擎原生 API;ID 必须落在规定范围(精灵 1001–3000、群组 ≥201、图层 101–200/弹窗 301–400,另有 501–600、701+ 备用段,框架保留 1–1000 及 3001+ 等交替段)。
|
- **精灵只走 SpriteManager**:UI 代码**禁止**直接调 `GameABCUtils` 或引擎原生 API;ID 必须落在规定范围(精灵 1001–3000、群组 ≥201、图层 101–200/弹窗 301–400,另有 501–600、701+ 备用段,框架保留 1–1000 及 3001+ 等交替段)。
|
||||||
- **常量集中、禁硬编码**:精灵 ID/图片资源 ID/坐标尺寸/动画时长/音效 ID 一律定义在对应常量文件,业务代码引用,**不内联裸值**。
|
- **常量集中、禁硬编码**:精灵 ID/图片资源 ID/坐标尺寸/动画时长/音效 ID 一律定义在对应常量文件,业务代码引用,**不内联裸值**。
|
||||||
|
- **服务端权威、前端只展示**:核心运算与胜负裁定以服务端为准、数据以服务端为权威;前端只做界面展示与玩家交互,本地数据仅为渲染副本,不做权威计算。
|
||||||
- **组件走 BaseComponent**:UI 组件继承 `BaseComponent`,事件用 `this.addEventListener` 注册(`destroy()` 自动清理,防泄漏);动态精灵/定时器在 `onDestroy` 清理。
|
- **组件走 BaseComponent**:UI 组件继承 `BaseComponent`,事件用 `this.addEventListener` 注册(`destroy()` 自动清理,防泄漏);动态精灵/定时器在 `onDestroy` 清理。
|
||||||
- **数据优先、表现延后**:收到推送先改数据模型,再播动画,动画回调里刷新静态界面;动画期间**不改数据**。即使不播动画,重画函数也能据本地数据还原正确界面。
|
- **组件数据自持 + set-refresh**:组件自有数据集中 `this.data`;每个 UI/零件有 `setXxx`(只写数据)/`refreshXxx`(只据数据画)对,组件有总 `refresh()` 可据数据重建界面。
|
||||||
|
- **数据优先、表现延后**:收到推送先 `setXxx` 写数据、再播动画;动画的开始/结束/出错回调里**只刷界面、不写核心数据**。即使动画缺失/卡住/出错,数据、逻辑、界面仍正确、互不影响。
|
||||||
- **成败只认 `data.success`**:前端一律 `if (!data.success)` 判成败,**不**用 `status`/`code`,**不**写 `status` 兼容兜底。
|
- **成败只认 `data.success`**:前端一律 `if (!data.success)` 判成败,**不**用 `status`/`code`,**不**写 `status` 兼容兜底。
|
||||||
- **收发包走统一通道**:发包经统一发送封装(底层 `RpcHelper` 自动注入平台字段),收包统一分发(一 rpc 一处理器);业务逻辑放处理器,**不**写进 `Game_Modify.*`。
|
- **收发包走统一通道**:发包经统一发送封装(底层 `RpcHelper` 自动注入平台字段),收包统一分发(一 rpc 一处理器);业务逻辑放处理器,**不**写进 `Game_Modify.*`。
|
||||||
- **shared 只读**:`01_SubGame/codes/shared/` 是服务端 `shared/` 的同步副本,**不在前端改**,改服务端权威源后跑同步脚本。
|
- **shared 只读**:`01_SubGame/codes/shared/` 是服务端 `shared/` 的同步副本,**不在前端改**,改服务端权威源后跑同步脚本。
|
||||||
@@ -70,6 +73,7 @@ BaseComponent / UIManager(ui,组件化与场景) ← gameabc-framework(
|
|||||||
|
|
||||||
## 与既有文档的关系
|
## 与既有文档的关系
|
||||||
|
|
||||||
- 服务端的对应文档在 [`server/docs/development-guide/`](../../../server/docs/development-guide/);前端「成败标志 `data.success`」「收发包链路」与之同源,互为对照。
|
- 服务端的对应文档在 [`docs/server/development-guide/`](../../server/development-guide/);前端「成败标志 `data.success`」「收发包链路」与之同源,互为对照。
|
||||||
- 子游戏前端各层可能另有局部说明文档;本套是总纲,与之不冲突时以本套的通用原则为准。
|
- 子游戏前端各层可能另有局部说明文档;本套是总纲,与之不冲突时以本套的通用原则为准。
|
||||||
|
- **平台无关的通用工程与架构规范**(分层、可扩展模式、配置化、数据权威、反模式与审查清单)见 [`docs/games/engineering/`](../../games/engineering/):本套讲前端接入与红线,`engineering/` 讲前后端通用的设计方法论,互补阅读。
|
||||||
</content>
|
</content>
|
||||||
|
|||||||
@@ -61,6 +61,6 @@
|
|||||||
| 各端 `development-guide/` | 平台接入 + 工程红线(**能跑、合规**) |
|
| 各端 `development-guide/` | 平台接入 + 工程红线(**能跑、合规**) |
|
||||||
| `docs/architecture/` | **本系统**的具体架构说明(是什么样) |
|
| `docs/architecture/` | **本系统**的具体架构说明(是什么样) |
|
||||||
| `.github/copilot/skills/data-authority-principle.md` | 数据权威原则(本套 03 篇在其上扩展到前后端) |
|
| `.github/copilot/skills/data-authority-principle.md` | 数据权威原则(本套 03 篇在其上扩展到前后端) |
|
||||||
| **本套 `docs/engineering/`** | **平台无关的通用工程与架构规范**(该怎么设计) |
|
| **本套 `docs/games/engineering/`** | **平台无关的通用工程与架构规范**(该怎么设计) |
|
||||||
|
|
||||||
> 具体命名(模块名/文件名/方法名)在本套文档里多为**示例、可自定**;约束的是**做法与结构**,不是具体名字。
|
> 具体命名(模块名/文件名/方法名)在本套文档里多为**示例、可自定**;约束的是**做法与结构**,不是具体名字。
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
- `app/route/rpc` 三字段驱动三层路由(见 01)。
|
- `app/route/rpc` 三字段驱动三层路由(见 01)。
|
||||||
- `data` 里**必含平台参数**:`agentid`、`playerid`、`gameid`、`roomcode`、`seat` 等;数值参数收包时要 `parseInt`。
|
- `data` 里**必含平台参数**:`agentid`、`playerid`、`gameid`、`roomcode`、`seat` 等;数值参数收包时要 `parseInt`。
|
||||||
- **一包多信息**:一个响应包应携带本次状态变更的完整信息(出了什么牌、轮到谁、各家剩余、倒计时、比分……),减少往返。
|
- **一包多信息**:一个响应/推送包应带全「本次状态变更」所需的核心数据(出了什么牌、轮到谁、各家剩余、倒计时、比分……),使前端**仅凭本包 + 已有本地数据**就能把相关界面刷对——既减少往返,也避免"把一个界面状态拆成几个包拼、中途丢一个就停在自相矛盾的中间态"。("发全哪些"的具体要求见 §1.2。)
|
||||||
|
|
||||||
### 1.1 `route` / `routename` 从哪来、在哪定义、怎么匹配
|
### 1.1 `route` / `routename` 从哪来、在哪定义、怎么匹配
|
||||||
|
|
||||||
@@ -44,6 +44,18 @@
|
|||||||
|
|
||||||
> 一句话:**`routename` 在服务端 `cls_mod.new` 第二参定义(自定、应用内唯一),前端发包 `route` 必须与它逐字相同,平台据此把包投到你的模块**;改名要两端同步改。
|
> 一句话:**`routename` 在服务端 `cls_mod.new` 第二参定义(自定、应用内唯一),前端发包 `route` 必须与它逐字相同,平台据此把包投到你的模块**;改名要两端同步改。
|
||||||
|
|
||||||
|
### 1.2 发包必须自带前端界面所需的全部核心数据
|
||||||
|
|
||||||
|
**前端以服务端数据为权威——只做界面展示与交互、不做权威计算**(见 [`client 05`](../../client/development-guide/05-开发规范与红线.md))。推论落到服务端:**每个下发包都必须携带前端渲染/刷新该界面所需的全部核心数据**,让前端「据包写入数据 → 直接刷新出界面」,而**不需要前端自行推算、补全或兜底**。
|
||||||
|
|
||||||
|
- **界面要用的字段都要发全**:凡界面要显示、或前端 set/refresh 要用到的核心字段(出了什么牌、轮到谁、各家剩余张数、手牌/副露、分数/比分、倒计时锚点、庄家/座位、各类状态标志……)都要放进 `data`,不能让前端"猜"或本地推算权威结果。
|
||||||
|
- **漏发是服务端的缺陷,不许前端补**:前端遵循数据权威原则——权威字段缺失应显式报错/留空、不用 `|| 0`/`|| []` 兜造(见 client 05)。所以服务端漏发 = 前端界面缺数据,**修在服务端发包处,不在前端补洞**。
|
||||||
|
- **落实「一包多信息」(见 §1)**:本包要让前端**仅凭本包 + 已有本地数据**把相关界面刷对,别把一个界面状态拆成几个包拼(中途丢一个就停在自相矛盾的中间态)。
|
||||||
|
- **差异化但要发全**:每个座位只发它**该看到**的核心数据(手牌只发本人,见 §3),但"该看到的"必须发全、发准。
|
||||||
|
- **重连/中途加入发完整快照**:`get_deskinfo` 必须给出该座恢复整个界面所需的**全量**核心数据,让前端 `Reconnect` 据快照一次重画(见 §6.4、02)。
|
||||||
|
|
||||||
|
> 一句话:**服务端权威不仅是"服务端算",也是"服务端把界面要用的核心数据发全"——前端只据包渲染,不推算、不兜底。**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. 收包处理的固定步骤(在 handler 里)
|
## 2. 收包处理的固定步骤(在 handler 里)
|
||||||
@@ -241,7 +253,7 @@ if (!data.success) { /* 失败处理 */ return; }
|
|||||||
| 重连/中途加入 | `export.get_deskinfo` 的返回 | `Game_Modify.Reconnect(_deskinfo)` → 重画 |
|
| 重连/中途加入 | `export.get_deskinfo` 的返回 | `Game_Modify.Reconnect(_deskinfo)` → 重画 |
|
||||||
| 对局/推送 | RPC handler 或主动推送(按 `rpc`) | 收包分发表里同名 `rpc` 的处理器 |
|
| 对局/推送 | RPC handler 或主动推送(按 `rpc`) | 收包分发表里同名 `rpc` 的处理器 |
|
||||||
|
|
||||||
**改服务端下发结构 = 同步核对前端对应 `rpc` 的解析**;**新增一种推送 = 服务端选定 `rpc` + 前端在分发表加同名处理器**。任一端单方面改,另一端必按旧结构解析出错。前端侧的收发细节以 [`client/docs/development-guide/04-网络对接与启动编排`](../../../client/docs/development-guide/04-网络对接与启动编排.md) 为权威。
|
**改服务端下发结构 = 同步核对前端对应 `rpc` 的解析**;**新增一种推送 = 服务端选定 `rpc` + 前端在分发表加同名处理器**。任一端单方面改,另一端必按旧结构解析出错。前端侧的收发细节以 [`docs/client/development-guide/04-网络对接与启动编排`](../../client/development-guide/04-网络对接与启动编排.md) 为权威。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -254,6 +266,7 @@ if (!data.success) { /* 失败处理 */ return; }
|
|||||||
## 8. 小结
|
## 8. 小结
|
||||||
|
|
||||||
- 包结构恒为 `{app, route, rpc, data}`;收包先 `check_player`,失败静默 `return`。
|
- 包结构恒为 `{app, route, rpc, data}`;收包先 `check_player`,失败静默 `return`。
|
||||||
|
- **下发包必须发全前端界面所需的核心数据**(§1.2):前端以服务端为权威、不自算,漏发修在服务端发包处、前端不补洞。
|
||||||
- 三种发包方式按"谁该看到什么"选;差异化广播逐座位定制,敏感信息只发本人。
|
- 三种发包方式按"谁该看到什么"选;差异化广播逐座位定制,敏感信息只发本人。
|
||||||
- **主动推送是唯一可靠下发通道**,`return` 不算。
|
- **主动推送是唯一可靠下发通道**,`return` 不算。
|
||||||
- **成败只认 `data.success`**,推送必自带 `success`,禁止 `status`/`code` 判成败与兼容兜底。
|
- **成败只认 `data.success`**,推送必自带 `success`,禁止 `status`/`code` 判成败与兼容兜底。
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ o_room.method.sendpack_toseat 按座位取连接信息(conmode/fromid) → 下
|
|||||||
- **平台框架**负责:网络收发、应用/模块/房间/玩家对象、路由、房卡、战绩、房间生命周期。
|
- **平台框架**负责:网络收发、应用/模块/房间/玩家对象、路由、房卡、战绩、房间生命周期。
|
||||||
- **子游戏**负责:玩法规则、对局状态、每个操作的处理与广播。两者通过 **export / import** 两组接口对接。
|
- **子游戏**负责:玩法规则、对局状态、每个操作的处理与广播。两者通过 **export / import** 两组接口对接。
|
||||||
|
|
||||||
> 上图是**入站半程**(前端 → 服务端 handler)。完整的往返链路(含服务端 `sendpack_toseat` 推回 → 前端 `Game_Modify._ReceiveData` 按 `rpc` 分发)见 [03 §6「端到端收发全链路」](./03-数据收发与通信协议.md#6-端到端收发全链路前后端对照),前端侧细节见 [`client/docs/development-guide/04`](../../../client/docs/development-guide/04-网络对接与启动编排.md)。
|
> 上图是**入站半程**(前端 → 服务端 handler)。完整的往返链路(含服务端 `sendpack_toseat` 推回 → 前端 `Game_Modify._ReceiveData` 按 `rpc` 分发)见 [03 §6「端到端收发全链路」](./03-数据收发与通信协议.md#6-端到端收发全链路前后端对照),前端侧细节见 [`docs/client/development-guide/04`](../../client/development-guide/04-网络对接与启动编排.md)。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -84,15 +84,15 @@ o_room.method.sendpack_toseat 按座位取连接信息(conmode/fromid) → 下
|
|||||||
- **模块职责边界**:一个职能只在一个模块实现,其他模块**调用而非重造**。
|
- **模块职责边界**:一个职能只在一个模块实现,其他模块**调用而非重造**。
|
||||||
- **房间隔离**:一切随对局变化的状态都挂 `o_room.o_desk.data.*`;**禁止模块级单例/全局变量存对局态**;缓存/定时器/决策表不得只用 `seat` 作 key,必须 `房间 + seat`;结束/解散/开新局时按房间清理全部定时器与残留状态。
|
- **房间隔离**:一切随对局变化的状态都挂 `o_room.o_desk.data.*`;**禁止模块级单例/全局变量存对局态**;缓存/定时器/决策表不得只用 `seat` 作 key,必须 `房间 + seat`;结束/解散/开新局时按房间清理全部定时器与残留状态。
|
||||||
- **服务端自动操作复用真人链路**:服务端代替玩家做的操作(如 AI 托管)必须复用「真人操作」的同一套处理入口与广播链路,对前端透明,不为它单开一套下发分支。
|
- **服务端自动操作复用真人链路**:服务端代替玩家做的操作(如 AI 托管)必须复用「真人操作」的同一套处理入口与广播链路,对前端透明,不为它单开一套下发分支。
|
||||||
- **服务器权威**:房卡、胜负、积分、状态等关键数据与操作一律以服务器为准,前端数据仅供显示。
|
- **服务器权威 + 发全下发面**:房卡、胜负、积分、状态等关键数据与操作一律以服务器为准、前端只作显示不自算;因此**服务端每个下发包必须携带前端界面所需的全部核心数据**,漏发修在服务端发包处、前端不补(详见 03 §1.2 / 04 §4)。
|
||||||
- **测试纪律**:测试失败先用证据裁定「业务缺陷 vs 测试脚本缺陷」,禁止 skip/软化断言/吞异常掩盖;**正式代码不得为兼容测试而加逻辑**。
|
- **测试纪律**:测试失败先用证据裁定「业务缺陷 vs 测试脚本缺陷」,禁止 skip/软化断言/吞异常掩盖;**正式代码不得为兼容测试而加逻辑**。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 与既有文档的关系
|
## 与既有文档的关系
|
||||||
|
|
||||||
- 平台级、面向「所有子游戏」的总纲在 `docs/important/server/`(友乐框架收发包规范、子游戏开发要求)。
|
- 本套文档是**落地版**:结合本仓库真实代码,给出可直接照做的接入步骤与红线,并对其中已被本项目实践修正的部分(如成败标志由 `status` 收敛为 `success`)以本套为准。
|
||||||
- 本套文档是其**落地版**:结合本仓库真实代码,给出可直接照做的接入步骤与红线,并对其中已被本项目实践修正的部分(如成败标志由 `status` 收敛为 `success`)以本套为准。
|
|
||||||
- 各子游戏内部的架构细节(模块划分、算法)仍以各自 `<游戏容器目录>/<游戏>/docs/` 为准。
|
- 各子游戏内部的架构细节(模块划分、算法)仍以各自 `<游戏容器目录>/<游戏>/docs/` 为准。
|
||||||
|
- **平台无关的通用工程与架构规范**(分层、可扩展模式、配置化、数据权威、反模式与审查清单)见 [`docs/games/engineering/`](../../games/engineering/):本套讲"平台怎么接、红线是什么",`engineering/` 讲"该怎么设计、怎么长久演进",互补阅读。
|
||||||
</content>
|
</content>
|
||||||
</invoke>
|
</invoke>
|
||||||
|
|||||||
Reference in New Issue
Block a user