初始化仓库:友乐/gameabc 房卡游戏平台脚手架(client + server + docs)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 18:13:26 +08:00
co-authored by Claude Opus 5
commit 594820d393
655 changed files with 310861 additions and 0 deletions
@@ -0,0 +1,144 @@
# 01 · 架构总则与分层
本篇给出七大架构总则,并落到一套**前后端参考分层**上。总则是"为什么这么设计",分层是"具体长什么样"。
所有分层里的模块名均为**示例、可自定**,约束的是**层与依赖方向**,不是名字。
---
## 1. 七大架构总则
### 1.1 单一权威数据源(Single Source of Truth)
同一业务数据**只能有一个计算/写入的地方**,其余模块只读取、不重算。多处并行计算同一结果,必随
规则演化而分叉、互相矛盾。
- 上游**算 + 写 + 校验**,下游**只读 + 消费**。
- 需要某数据时,**读权威源**,而不是"顺手再算一遍"。
- 详见 [03 篇 · 数据权威](./03-数据权威·错误处理·演进.md)。
### 1.2 单向依赖,禁止环
分层之间**自上而下单向依赖**:入口依赖编排、编排依赖领域、领域依赖数据/共享;**反向不依赖**。
- **稳定依赖原则**:越被依赖的层越应稳定(领域/共享层最稳定,入口层最易变)。
- **禁止环形依赖**:A 依赖 B、B 又依赖 A,是"职责没分清"的信号,应抽出共同依赖或调整边界。
- 双运行时下尤其致命:环依赖 + 中途 `require` 会在浏览器端崩溃(见 development-guide 的 require 守卫)。
### 1.3 职责单一、边界清晰
**一个职能只在一个模块实现**,别的模块需要它就**调用**,不"图方便"复制一份近似逻辑。
- 判据:写代码前先问"这段逻辑属于谁的职责"。属于别人的,就调用它。
- 权威能力不满足时,**在权威模块内扩展**,不要在调用方旁路重写。
- 反例:在 A 模块内联 B 模块核心算法的"简化版";同一职能两处并行演化。
### 1.4 关注点分离(Separation of Concerns)
把"不同变化原因"的代码分开,让每块**只因一个原因而改**:
| 分离维度 | 一侧 | 另一侧 |
|----------|------|--------|
| 决策 vs 机制 | "选哪个"(策略/决策) | "怎么做"(算法/规则/执行) |
| 数据 vs 表现 | 状态模型(真相) | 渲染/UI(从数据重建) |
| 编排 vs 算法 | 流程编排(controller) | 纯计算(领域算法) |
| 输入 vs 逻辑 | 收发包/参数校验 | 业务处理 |
> 例(决策 vs 机制):自动操作模块只决定"打哪张/是否碰杠胡过",**不实现**胡牌检测/听牌分析;
> 后者是领域算法,决策层只**读取其结果**。这既是关注点分离,也是职责边界。
### 1.5 对扩展开放、对修改封闭(OCP)
新增一种玩法/规则/策略/牌型,应当是**新增一段代码并注册**,而**不是**去改动已经稳定、已被测试
覆盖的核心流程。
- 手段:**注册表 + 策略**、**管线/中间件**、**工厂**(见 [02 篇](./02-可扩展性与配置化.md))。
- 收益:核心不动 → 回归风险小;扩展点清晰 → 新人能照葫芦画瓢。
- 例:分级决策框架——核心是"取上下文 → 跑管线 → 选结果",新增高级策略只是**写策略对象 +
注册 + 单测**三步,核心零改动。
### 1.6 配置优先于硬编码
**会变的、复用的、无语义的**值不写死在逻辑里,外提为常量/配置,用**数据驱动行为**。
- 分数、阈值、类型字符串、跨模块 key → 常量;成套玩法开关 → 配置对象/规则编码。
- 让"改规则"变成"改配置",而不是"改代码 + 重测逻辑"。
- 详见 [02 篇 · 配置化与去硬编码](./02-可扩展性与配置化.md)。
### 1.7 显式失败优于隐式兜底
关键路径上数据缺失,**优先报错或返回 `null`**,把问题暴露在**离根因最近**的地方;不要用
`|| 0`、`|| []`、`|| ''`、双源回退把缺失悄悄填平。
- 兜底会把 bug 藏进"看似正常"的流程里,等到很远的下游才爆发,极难定位。
- 只有**展示层、纯 UI 兼容、非关键日志**字段,才可在明确边界内用安全默认值。
- 详见 [03 篇](./03-数据权威·错误处理·演进.md)。
---
## 2. 前后端参考分层
下面是一套**成熟、可直接照搬思路**的分层。层次是稳定的,层内文件如何组织由子游戏自定。
### 2.1 后端分层(自上而下依赖)
```
┌─────────────────────────────────────────────┐
│ 入口层 Entry 收包薄委托:一操作一入口,只接住并转交 │ 易变
├─────────────────────────────────────────────┤
│ 收发层 IO 参数校验、响应构建、序列化、差异化广播 │
├─────────────────────────────────────────────┤
│ 编排层 Orchestrate 流程编排、状态机推进、跨模块协调(不含算法) │
├─────────────────────────────────────────────┤
│ 领域层 Domain 规则/算法权威实现(胡牌/听牌/计分/牌型…) │
├─────────────────────────────────────────────┤
│ 数据层 Data 对局状态、状态管理、统一访问层 │
├─────────────────────────────────────────────┤
│ 共享层 Shared 前后端逐字相同的纯逻辑与常量 │ 最稳定
└─────────────────────────────────────────────┘
依赖方向:上层 → 下层(下层绝不反向依赖上层)
```
- **入口层薄**:只做"接住请求 → 委托",不写业务;一操作一入口,不做二次路由。
- **领域层是权威**:所有"能不能胡/听什么/怎么算分"的算法只此一份,别层调用。
- **数据层是唯一状态落点**:对局状态集中管理,读写走统一访问层,避免散落。
- **共享层最底、最稳定**:见 [03 篇 · 数据权威] 与各端 development-guide 的 shared 说明。
### 2.2 前端分层(自上而下依赖)
```
┌─────────────────────────────────────────────┐
│ 入口层 Entry 平台受限入口:只解包转交,不写业务 │ 易变
├─────────────────────────────────────────────┤
│ 分发层 Dispatch 唯一收包口,按 rpc 路由到处理器(纯路由表) │
├─────────────────────────────────────────────┤
│ 处理层 Controllers 一类消息一处理器:改数据模型 / 触发表现 │
├─────────────────────────────────────────────┤
│ 状态层 Model 前端状态真相(界面从它无歧义重建) │
├─────────────────────────────────────────────┤
│ 表现层 View/Managers 渲染、动画、音频、资源(从状态派生) │
├─────────────────────────────────────────────┤
│ 共享层 Shared 与服务端同源的纯逻辑(只读同步副本) │ 最稳定
└─────────────────────────────────────────────┘
表现从状态派生:任何时刻重画都能还原正确界面
```
- **入口只转交**:平台受限入口不堆业务,逻辑全在处理层。
- **收包分发只分发**:一张 `rpc → 处理器` 路由表,不在分发口写业务。
- **数据优先、表现延后**:先落状态模型,再由表现层派生;重连=重画,与正常对局**复用同一重画路径**。
### 2.3 依赖方向自检
- 有没有"下层反过来 import/引用上层"?有 → 边界错位,重划。
- 有没有"两个模块互相依赖"?有 → 抽公共依赖或合并职责。
- 有没有"入口层里写了算法/规则"?有 → 下沉到领域层。
- 有没有"表现层里存了业务真相"?有 → 上移到状态层。
---
## 3. 本篇小结
- 七大总则:**SSOT、单向依赖、职责单一、关注点分离、OCP、配置优先、显式失败**。
- 后端六层(入口/收发/编排/领域/数据/共享)、前端六层(入口/分发/处理/状态/表现/共享),**依赖单向向下**。
- 层是稳定的,层内组织自定;判断对错的尺子始终是**依赖方向**与**职责归属**。
下一篇 [02-可扩展性与配置化](./02-可扩展性与配置化.md):把 OCP 与"配置优先"落成具体模式与判据。
@@ -0,0 +1,147 @@
# 02 · 可扩展性与配置化
本篇把总则里的 **OCP(对扩展开放)** 和 **配置优先** 落成可直接套用的模式与判据,
并给出**避免过度设计**的红线——扩展性是为了"改得动",不是为了炫技。
---
## 1. 可扩展性模式(够用就好)
下面几种模式覆盖子游戏绝大多数扩展需求。**先问"现在真的需要扩展吗",需要再用**(见 §3)。
### 1.1 注册表 + 策略(Registry + Strategy)— 最常用
把"一族可替换的行为"抽象成**策略对象**,用**注册表**收集,运行时按上下文选一个执行。
新增行为 = 写一个策略 + 注册,**核心零改动**。
```
Registry(注册表) ── register(strategy) ──▶ [strategyA, strategyB, ...]
│
Context(只读上下文)──▶ 选择器 select(ctx) ─────────┘──▶ 命中的策略.execute(ctx)
```
- **适用**:AI 决策分级、规则变体、牌型识别族、结算规则族——"同一类事有多种做法"。
- **要点**:
- 策略只依赖**只读上下文**,不反向修改全局;上下文封装它需要的权威数据。
- 有**默认策略兜底**(保证任何输入都有结果),高级策略**按需叠加**。
- 策略之间**互不知道**对方,新增不影响既有。
- **例**:分级决策框架——`Context/Registry/Pipeline + 基础策略 + 占位高级策略`,默认走最低级,
高级留扩展点;新增高级策略三步(写策略对象 + register + 单测)零侵入。
### 1.2 管线 / 中间件(Pipeline)
把一个复杂处理拆成**有序的小步骤**,每步只做一件事、可独立增删。
```
输入 ──▶ [校验] ──▶ [规则A] ──▶ [规则B] ──▶ [收敛] ──▶ 输出
每一节点单一职责,可插拔、可测试
```
- **适用**:决策流水线、校验链、结算的多阶段计分(比精 → 冲关 → 霸王 → 零和)。
- **要点**:节点间用**明确的数据结构**传递,不靠隐式全局;任一节点可单测。
### 1.3 工厂(Factory)
把"根据类型创建/选择实现"的分支收敛到一处,调用方只要"我要一个 X",不关心怎么造。
- **适用**:胡牌检测按牌型分派、可用操作枚举、不同房型的配置构建。
- **要点**:工厂是**唯一**的创建入口,避免 `if(type==...)` 散落各处(那是并行逻辑的温床)。
- **例**:胡牌检测工厂——检测逻辑只此一份,各处调用它,不自行手搓顺子/搭子判定。
### 1.4 事件总线(EventBus)— 前端解耦,谨慎用
用发布/订阅让"状态变化"与"表现响应"解耦:处理器改完数据 `emit` 事件,表现层订阅刷新。
- **适用**:一次数据变化要驱动多个互不相关的表现(动画 + 音效 + 计分板)。
- **克制**:
- **不要**用事件做"隐式流程控制"——关键流程的因果应显式可追踪,别埋进一堆事件里。
- 事件是**通知**,不是**命令**;订阅方不该反向决定发布方的流程。
- 能直接函数调用讲清的因果,就别为"解耦"硬拆成事件。
### 1.5 统一访问层(Facade over data)
对"读权威数据"提供一个**统一入口**(如 DataAccessHelper 之类),下游都走它读,不各自摸索
数据结构。好处:数据结构演化时只改访问层一处;配合"缺失显式失败",把校验集中。
---
## 2. 配置优先于硬编码
目标:**让"会变的东西"从代码逻辑里分离出来,用数据驱动**。改规则变成改配置,而非改逻辑 + 重测。
### 2.1 什么必须外提(满足任一即提取)
| 判据 | 说明 | 典型 |
|------|------|------|
| **会变** | 规则调整时可能改动 | 分数值、阈值、倍率、局数、超时 |
| **复用** | 超过一个模块用到同一值 | 跨模块共享的 key、类型标识 |
| **无语义** | 裸值无法自解释业务含义 | 魔法数字、状态字符串 |
按语义归入分层的常量文件(**分数/计分类、规则配置类、类型枚举类**……),不要一个巨型常量堆。
### 2.2 什么不必外提(避免过度设计)
- 单函数内一次性的临时值(循环初值 `0`、空数组 `[]`)。
- 框架约定的固定串(模块加载路径等)。
- 自解释的布尔开关、纯展示标点文字。
> 三问法:**会变吗?复用吗?有语义需要命名吗?** 三个都"否",就地内联,别为提取而提取。
### 2.3 规则驱动:把玩法开关变成数据
复杂玩法的差异(人数/局数/扣卡方式/各种开关)应编码成**一份配置**,在入口处**解析一次**,
之后全流程**只读消费**:
```
房型/配置编码 ──(解析器,解析一次)──▶ 规则对象(结构化、只读)
│
各模块按需读取规则对象的字段,不再各自解析原始编码、不再散落 if
```
- **解析只此一处**:避免"多处各自解析同一编码"产生的不一致(这是 SSOT 在配置上的体现)。
- **规则对象只读**:下游不回写、不推断缺省;缺字段是**配置或解析的 bug**,应显式暴露。
- **新增一个玩法开关** = 编码加一位 + 解析器认它 + 消费点读它,**不改无关逻辑**。
### 2.4 配置注入优于全局魔法值
模块需要的配置**从入口传入 / 从权威配置对象读取**,而不是在模块内部埋一堆魔法值或直接摸全局。
这让模块**可测试**(注入不同配置跑用例)、**可复用**(换配置即换行为)。
---
## 3. 避免过度设计(同等重要的红线)
可扩展性有成本:抽象层、间接跳转、认知负担。**过度设计和硬编码一样有害**。
### 3.1 什么时候**不要**加抽象
- **只有一种实现、且看不到第二种的现实需求** → 不要为"将来也许"预留策略/工厂。先写直接实现。
- **YAGNI**:没有当前需求的扩展点就是负债;等第二个变体真的出现,再**重构**成模式(那时你更懂共性)。
- **一次性逻辑** → 不要包装成"通用框架"。通用性从**重复中提炼**,不是凭空设计。
### 3.2 判断"值不值得抽象"
| 加抽象 | 别加抽象 |
|--------|----------|
| 已有 ≥2 个真实变体,且还会增加 | 只有 1 个实现,扩展是想象的 |
| 变体频繁新增(规则/策略/牌型) | 逻辑稳定,多年不变 |
| 核心被扩展反复改动、回归频发 | 改动集中、影响面小 |
| 抽象后核心显著变简单、变稳定 | 抽象后跳转变多、更难读 |
### 3.3 成熟的判据:三次法则 + 就近演进
- **三次法则**:同样的东西第 3 次出现时再抽象;第 1、2 次容忍重复。
- **就近演进**:先把直接实现写对、写清;当扩展点**自然浮现**(真来了第二个变体),
再**收敛**成注册表/策略——此时抽象是"被现实拉出来的",最贴合,也最不会过度。
> 一句话:**扩展性是留给"已知会变"的地方的;对"稳定不变"的地方,简单直接才是最好的设计。**
---
## 4. 本篇小结
- 扩展四件套:**注册表+策略、管线、工厂、事件总线(谨慎)**,外加**统一访问层**;够用即止。
- 配置化:会变/复用/无语义→外提;玩法差异→规则对象解析一次、只读消费;配置注入优于全局魔法值。
- 反过度设计:**YAGNI + 三次法则 + 就近演进**;只有一种实现就别造框架,抽象从重复中提炼。
下一篇 [03-数据权威·错误处理·演进](./03-数据权威·错误处理·演进.md):把"正确性"的地基——数据权威、错误处理、演进纪律——讲透。
@@ -0,0 +1,147 @@
# 03 · 数据权威 · 错误处理 · 演进
本篇是**正确性**的地基:数据从哪来、错了怎么暴露、代码怎么随规则长大而不腐化。
数据权威部分在 `.github/copilot/skills/data-authority-principle.md` 基础上,扩展到**前后端全景**。
---
## 1. 数据权威(前后端全景)
### 1.1 四条铁律(承接数据权威原则)
1. **数据源唯一**:同一业务数据只有一个权威来源;上游算/写/校验,下游只读/消费,**不重复推断、不重复拼装**。
2. **禁止猜测兜底**:不用默认值掩盖缺失。关键权威字段缺失要**显式报错或返回 `null`**,由上层决定是否终止;
**禁止** `|| 0`、`|| []`、`|| ''`、双源回退等隐式掩盖。
3. **下游不修补**:下游不得为"让流程跑起来"而补写/重算上游本应提供的数据;发现下游在修补,**把责任前移到权威源**。
4. **边界内可默认**:只有**展示层、纯 UI 兼容、非关键日志**字段,才可在明确边界内用安全默认值。
### 1.2 前后端的权威划分
```
权威裁定 表现/预判
┌──────────────────────┐ ┌──────────────────────┐
│ 服务端 = 真相之源 │ 推送 │ 前端 = 从推送重建表现 │
│ 房卡/胜负/积分/发牌/ │ ─────▶ │ 只显示、可预校验, │
│ 手牌/状态/结算…全权威 │ │ 不"前端说了算" │
└──────────────────────┘ └──────────────────────┘
▲ 同一套 shared 纯逻辑(逐字相同)在两端各跑一份 ▲
└──────────────────────────────────────────────┘
```
- **服务端权威**:一切影响胜负/计分/状态的判定以服务端为准;前端结果只是**表现与预判**。
- **逻辑同源 ≠ 权威转移**:前后端共享同一套算法(shared)是为了**表现一致 + 预校验**,
最终仍以服务端算的为准(见各端 development-guide 的 shared 说明)。
- **一份数据一个方向**:产生 → 推送 → 消费,单向、可追踪;前端不把"预判结果"当权威回写。
### 1.3 审查信号
看到 `|| []`、`|| 0`、`|| ''`、三元默认、双源字段——先判断它是不是**权威字段**(影响发牌/庄家/
手牌/规则/结算/重连/状态流转):
- **是** → 改成权威读取(缺失显式失败)。
- **只是展示/日志/统计** → 才可保留默认值。
---
## 2. 错误处理与可观测性
### 2.1 fail-fast:把错误暴露在最近处
- 关键路径缺前置条件(缺权威数据、状态非法),**立即中止**并给出明确错误,别带病继续。
- **不吞异常**:`try/catch` 不是用来"让它别报错",而是用来**在正确的边界处理并记录**。空 `catch{}`
等于把故障藏起来,是重大反模式。
- **校验前置**:入口处集中校验参数/状态,不合法即返回;业务逻辑内部可假设前置条件已满足。
### 2.2 错误的分层归属
| 层 | 出错时怎么办 |
|----|--------------|
| 入口/收发层 | 参数/身份/状态校验失败 → 结束请求(对外不泄漏细节,见 development-guide 的"静默 return") |
| 编排层 | 前置条件不满足 → 显式失败,不替下层补数据 |
| 领域/算法层 | 输入非法 → 抛错/返回 `null`,**不猜**一个"看起来对"的结果 |
| 数据层 | 权威字段缺失 → 显式失败,暴露数据链断点 |
| 表现层 | 可容错降级(缺图/缺文案用占位),**不影响业务判断** |
### 2.3 可观测性
- **分级日志**:关键节点(收包、状态转换、结算、扩展点命中)留可复盘的日志;日志**说清上下文**
(房间、座位、阶段),不是一句 "error"。
- **可复盘**:保留收包/关键中间态记录(如调试保存收包),出问题能重放。
- **诊断探针即用即清**:为定位问题临时加的日志/探针,**定位完成后必须删除**,不留在正式代码里。
- **正式代码不为测试服务**:不为"让测试过"在正式代码加 fallback/守卫/冗余字段;测试构造符合
生产契约的输入与 stub(详见 development-guide 的测试纪律)。
---
## 3. 演进与重构纪律
代码会随规则长大。让它**长而不腐**的关键,是持续把"并行/重复/临时"收敛掉。
### 3.1 收敛并行实现
- 同一职能出现**第二份实现**(哪怕是"简化版/兼容版"),就是分叉的开始——**尽快收敛为一份权威**。
- 收敛方向:把旁路实现删掉,改为调用权威模块;权威能力不足则**在权威模块内扩展**。
### 3.2 扩展点先行,而非到处开分支
- 需要支持新变体时,优先看**有没有现成扩展点**(策略注册/管线节点/工厂分派);有则加一项。
- 没有且已达"三次法则"→ **重构出扩展点**,再加变体;不要在核心里再堆一个 `if`。
### 3.3 死代码与"有意保留的扩展点"要区分
- **死代码**(不可达、被替代、幻觉引用)→ 删除,减少认知负担。
- **有意保留的扩展点**(当前不可达但为将来能力预留)→ **注释写明意图**,避免被当死代码清理,
也避免被误当"已实现"。二者的区别必须在代码里显性表达。
### 3.4 改动的提交纪律
- **一次提交聚焦一件事**(一个修复/一个功能/一处重构/一批测试),信息写清"做了什么/为什么"。
- 业务缺陷与测试缺陷**分开修、分开提交**;重构与功能改动不混在一个提交里。
---
## 4. 反模式清单(一眼识别)
| 反模式 | 为什么坏 | 正解 |
|--------|----------|------|
| 隐式兜底 `\|\| 0 / \|\| []` 掩盖缺失 | 把 bug 藏到远处才爆发 | 权威字段缺失显式失败/返回 null |
| 同一数据多处各算一遍 | 必然分叉、互相矛盾 | 单一权威源,下游只读 |
| 下游修补上游数据 | 责任错位,掩盖真问题 | 责任前移到权威源 |
| 入口/表现层里写算法 | 职责错层,难测难复用 | 下沉到领域/状态层 |
| 一个入口 `switch(action)` 二次路由 | 绕开分层、膨胀成上帝函数 | 一操作一入口/一 rpc 一处理器 |
| 空 `catch{}` 吞异常 | 故障隐形 | 在正确边界处理并记录 |
| 为"将来也许"预埋抽象 | 过度设计、徒增复杂 | YAGNI + 三次法则,就近演进 |
| 魔法数字/字符串散落 | 改规则要全局翻找 | 外提为语义化常量/配置 |
| 多处各自解析同一配置编码 | 解析不一致 | 解析一次 → 只读消费 |
| 同职能第二份"简化实现" | 并行逻辑分叉 | 收敛为一份权威,调用不重造 |
| 正式代码为测试加 fallback | 本末倒置 | 测试适配生产契约 |
| 诊断日志/探针遗留 | 噪声与信息泄漏 | 定位后即清 |
---
## 5. 架构审查清单
提交/评审前逐条自检(与 [01](./01-架构总则与分层.md)/[02](./02-可扩展性与配置化.md) 对应):
- [ ] **SSOT**:这段数据有没有第二处在算?下游是不是只读?
- [ ] **依赖方向**:有没有下层依赖上层 / 环依赖 / 入口层写算法?
- [ ] **职责边界**:这段逻辑属于本模块吗?是不是重造了别处的能力?
- [ ] **关注点分离**:决策与算法、数据与表现分开了吗?
- [ ] **扩展 vs 修改**:新增能力是"加+注册"还是"改核心"?该用扩展点吗?
- [ ] **不过度设计**:这个抽象有 ≥2 个真实变体吗?还是想象的?
- [ ] **配置化**:有会变/复用/无语义的裸值该外提吗?配置只解析一次吗?
- [ ] **显式失败**:关键路径缺数据是报错还是兜底掩盖?
- [ ] **错误处理**:有没有空 catch / 吞异常 / 带病继续?
- [ ] **可观测**:关键节点有可复盘日志吗?诊断探针清了吗?
- [ ] **演进**:有没有留下第二份并行实现 / 死代码没区分意图?
---
## 6. 本篇小结
- 数据权威四铁律 + 前后端权威划分:**服务端裁定、前端表现、shared 同源不转移权威**。
- 错误处理:**fail-fast、不吞异常、分层归属、可观测、诊断即清**。
- 演进:**收敛并行实现、扩展点先行、区分死代码与扩展点、一次一提交**。
- 用反模式清单和审查清单把三篇的原则落到每次改动上。
回到 [README](./README.md) 查看导航与一页纸总则。
+66
View File
@@ -0,0 +1,66 @@
# 子游戏前后端开发规范 · 工程与架构通则
> 本套文档总结一套**专业、成熟、平台无关**的子游戏开发规范。它不讲某个平台怎么接入,
> 而是从**架构与工程**的角度,给出前后端通用的设计原则、可扩展模式、配置化实践与反模式清单,
> 指导开发者写出**优雅、现代、易演进、少返工**的子游戏代码。
---
## 这套文档解决什么
平台接入细节(三层路由、export/import、收发包协议、ES5/require 等)已在各端
`development-guide/` 中讲清;本套文档是它们之上的**工程方法论**:
- **怎样分层**,让依赖单向、边界清晰、改一处不牵一身;
- **怎样扩展**,让新增玩法/规则/策略是"加代码"而非"改核心";
- **怎样配置化**,把会变的东西从硬编码里拿出来,用数据驱动;
- **怎样守住数据权威**,让同一份数据只有一个来源、缺失即显式失败;
- **怎样不过度设计**,在"能扩展"与"够简单"之间拿捏。
> 一句话定位:**平台接入是"能不能跑通",本套规范是"跑得久、改得动、错得少"。**
---
## 阅读导航
| 篇 | 文档 | 解决什么 |
|----|------|----------|
| 00 | 本文 README | 定位、适用范围、一页纸总则、与既有文档的关系 |
| 01 | [01-架构总则与分层.md](./01-架构总则与分层.md) | 七大架构总则;前后端参考分层;依赖方向与稳定依赖 |
| 02 | [02-可扩展性与配置化.md](./02-可扩展性与配置化.md) | 扩展模式(注册表/策略/管线/工厂/事件)何时用;配置化与去硬编码;避免过度设计 |
| 03 | [03-数据权威·错误处理·演进.md](./03-数据权威·错误处理·演进.md) | 数据权威(前后端);错误处理与可观测;演进与重构;反模式与审查清单 |
---
## 一页纸:七大总则
1. **单一权威数据源(SSOT)**:同一业务数据只有一个计算/写入处,其他只读;缺失即显式失败,不兜底掩盖。
2. **单向依赖**:分层自上而下依赖,稳定的被依赖、易变的作依赖方;**禁止环形依赖**。
3. **职责单一、边界清晰**:一个职能只在一个模块实现,别处**调用而非重造**。
4. **关注点分离**:决策与机制分离、数据与表现分离、编排与算法分离。
5. **对扩展开放、对修改封闭(OCP)**:用注册/策略/管线**加**能力,不改动已稳定的核心。
6. **配置优先于硬编码**:会变、复用、无语义的值一律外提为常量/配置,用数据驱动行为。
7. **显式失败优于隐式兜底**:关键路径缺数据就报错/返回 `null`,把问题暴露在最近处。
> 这七条互相支撑:**SSOT + 显式失败**保正确,**单向依赖 + 职责单一 + 关注点分离**保清晰,
> **OCP + 配置化**保可演进。任何设计取舍,回到这七条对照。
---
## 适用范围与边界
- **适用**:子游戏自身的前后端业务代码(玩法逻辑、对局编排、收发包处理、表现层、共享算法)。
- **不覆盖**:平台框架代码(不可改)、平台接入契约(见各端 `development-guide/`)。
- **与硬约束的关系**:ES5、`require` 守卫、可编辑范围、成败标志 `data.success` 等**硬红线**仍以
`development-guide/` 为准;本套是**方法论层**,与之互补不冲突。
## 与既有文档的关系
| 文档 | 定位 |
|------|------|
| 各端 `development-guide/` | 平台接入 + 工程红线(**能跑、合规**) |
| `docs/architecture/` | **本系统**的具体架构说明(是什么样) |
| `.github/copilot/skills/data-authority-principle.md` | 数据权威原则(本套 03 篇在其上扩展到前后端) |
| **本套 `docs/engineering/`** | **平台无关的通用工程与架构规范**(该怎么设计) |
> 具体命名(模块名/文件名/方法名)在本套文档里多为**示例、可自定**;约束的是**做法与结构**,不是具体名字。