二七王:UI 清单统一底牌术语,细化叫分按钮,确认 S-1 语义

术语修订(本文先行,design/protocol 待同步):
- 底牌 = 发牌时没发给玩家、留在桌面的 8 张(原「暗牌」)
- 埋牌底牌 = 庄家埋牌扣下的 8 张(原「底牌」)
改后底栏按钮名实相符(底牌钮看底牌、扣底钮看埋牌底牌),原「术语陷阱」
一节改写为「术语已统一」。新增 §0.0 术语节置于全文之首。
全文 35 处表述与精灵键名同步(DARK_CARD→BOTTOM_CARD、
BOTTOM_CARD→BURY_CARD、ANCARD_3S→BOTTOM_3S)。

S-3 定论:底牌可见性按 design 手册办——庄家全程可看,闲家仅 70 分坐庄局
可看,其余局按钮不显示。服务端无需改动,现有下发面正好支持。

新增两条服务端待补:
- S-4 拆分 bottomcards 字段名:底牌保持 bottomcards,埋牌底牌改 burycards
  (maipai / PushCards / 结算 bottom 分组)。前端未开工,现在改代价最小。
- S-5 同步 design.md 与 packet_protocol.md 的术语,并列出待改位置清单。
  三份文档术语不一致会直接违反 SSOT,属最危险的那类分歧。

S-1 语义确认:当前捡分对应判定倍率的实时预览(大光×3/小光×2/过庄×1/
升N级×N)。要求随 chupai1/2/3、PushCards、shangzhuang 一起下发
curmultiple,不新开推送包;get_upgrade 现成可用。

叫分按钮(据更新后的 叫分按钮面板.png):
- 配色按档位位置固定,只因不可叫变灰,不随子数变。
- 按钮底与右上角角标底画在同一张图上,4 帧。
- 叫分分数用数字精灵(新增资源 NUM_CALL_SCORE),角标子数用文字精灵。
- 每档由 4 个精灵改为 3 个。
数字口径相应从「一律图片多帧」改为分工:美术字用图片、纯数据小字用文字精灵。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-25 17:48:49 +08:00
co-authored by Claude Opus 5
parent 5dda571250
commit cfef896fd6
2 changed files with 156 additions and 102 deletions
+156 -102
View File
@@ -13,6 +13,7 @@
## 目录
- [0. 总则](#0-总则)
- [0.0 术语(本项目修订版)](#00-术语本项目修订版优先于-designmd)
- [0.1 设计基准与座位映射](#01-设计基准与座位映射)
- [0.2 平台已提供、子游戏不重建的部分](#02-平台已提供子游戏不重建的部分)
- [0.3 ID 号段规划](#03-id-号段规划)
@@ -38,6 +39,21 @@
## 0. 总则
### 0.0 术语(本项目修订版,优先于 design.md)
**2026-08-25 修订**:原 design.md 里「暗牌 / 底牌」的命名与界面按钮倒挂,现统一为:
| 术语 | 指哪 8 张 | design.md 原称 | 当前协议字段 |
| --- | --- | --- | --- |
| **底牌** | 发牌时**没有发给玩家**、留在桌面的 8 张 | ~~暗牌~~ | `shangzhuang.bottomcards`、`ChooseMain`/`BuryCards.bottomcards` |
| **埋牌底牌** | 庄家埋牌时从手里扣下的 8 张 | ~~底牌~~ | `maipai.bottomcards`、`PushCards.bottomcards`、结算 `bottom.cards` |
其余术语(埋牌、扣底、甩牌、毙牌、垫牌、捡分、子、奖…)沿用 design.md §1 不变。注意「**扣底**」仍指 design §6.3 那条规则——闲家用主牌赢下最后一轮后翻开**埋牌底牌**计分;底栏那个 `扣底` 按钮是「查看埋牌底牌」的入口,两者同名但不同义。
> ⚠️ **design.md 与 packet_protocol.md 尚未同步此变更**(见 §7.5 **S-5**)。在同步前,读那两份文档时要做一次心算转换;协议里两批牌**共用 `bottomcards` 字段名**,需按所在包判断语义(拆分建议见 **S-4**)。
---
### 0.1 设计基准与座位映射
| 项 | 值 | 来源 |
@@ -129,9 +145,9 @@ get_nextseat: function(seat){ return (seat + 1) % 3; }
| --- | --- | --- |
| **101** | `EQW_Table_Static` | 牌桌常驻:顶部信息条、玩家位附加标记、亮牌信息条、底栏(局数 + 功能钮) |
| **102** | `EQW_Hand` | 自己手牌区(单排 / 埋牌双排) |
| **103** | `EQW_TableCards` | 桌面牌:暗牌区、三家已出牌区、底牌展示区 |
| **103** | `EQW_TableCards` | 桌面牌:底牌区、三家已出牌区、埋牌底牌展示区 |
| **104** | `EQW_Action` | 阶段操作区:叫分面板、选主/投降面板、埋牌/出牌操作条、倒计时 |
| **105** | `EQW_Overlay` | 桌面浮层:提示气泡、报无主、甩错、捡分飘字、70 分暗牌亮 3 秒 |
| **105** | `EQW_Overlay` | 桌面浮层:提示气泡、报无主、甩错、捡分飘字、70 分底牌亮 3 秒 |
| **302** | `EQW_Popup_AsetResult` | 小局结算 |
| **303** | `EQW_Popup_Account` | 大局总结算 / 解散结算 |
| **304** | `EQW_Popup_History` | 出牌历史面板 |
@@ -149,9 +165,9 @@ get_nextseat: function(seat){ return (seat + 1) % 3; }
| 205 | 底栏功能按钮组(明牌 / 已出牌 / 上一轮 / 底牌) |
| 206 | 亮牌信息条 |
| 210 | 自己手牌 |
| 211 | 暗牌区(8 张) |
| 211 | 底牌区(发牌留桌 8 张) |
| 212 / 213 / 214 | 自己 / 左上家 / 右上家 的已出牌区 |
| 215 | 底牌展示区(结算时 8 张) |
| 215 | 埋牌底牌展示区(结算时 8 张) |
| 220 | 叫分面板 |
| 221 | 选主 / 投降面板 |
| 222 | 埋牌操作条 |
@@ -171,7 +187,7 @@ get_nextseat: function(seat){ return (seat + 1) % 3; }
| 1001–1099 | 顶部信息条 + 亮牌条 + 底栏(局数、功能钮) | ~30 |
| 1100–1199 | 三家玩家位附加标记 + 三处倒计时 | ~24 |
| 1200–1249 | 自己手牌 36 张 + 牌上标记 | ~45 |
| 1250–1299 | 暗牌 8 张 + 底牌 8 张 | 16 |
| 1250–1299 | 底牌 8 张 + 埋牌底牌 8 张 | 16 |
| 1300–1399 | 自己已出牌区(28 张 + 牌型标签) | ~30 |
| 1400–1499 | 左上家已出牌区(28 张 + 牌型标签) | ~30 |
| 1500–1599 | 右上家已出牌区(28 张 + 牌型标签) | ~30 |
@@ -269,9 +285,9 @@ var CARD_BACK_FRAME = 55; // 牌背(二七王固定用牌背
| 资源 ID | 键名 | 用途 | 单帧尺寸 | 整图尺寸 (10×6) |
| --- | --- | --- | --- | --- |
| 501 | `CARD_FACE_L` | 自己手牌、暗牌区 | **110 × 190** | 1100 × 1140 |
| 501 | `CARD_FACE_L` | 自己手牌、底牌区 | **110 × 190** | 1100 × 1140 |
| 502 | `CARD_FACE_M` | 三家已出牌区 | **90 × 155** | 900 × 930 |
| 503 | `CARD_FACE_S` | 结算底牌区 | **50 × 70** | 500 × 420 |
| 503 | `CARD_FACE_S` | 结算埋牌底牌区 | **50 × 70** | 500 × 420 |
> 单帧尺寸为参考图实测估值(§6),出图前请与最终设计稿核对。三套的**帧排列完全一致**,只有尺寸不同,`cardIdToFrame` 对三套通用。
@@ -290,7 +306,7 @@ var CARD_BACK_FRAME = 55; // 牌背(二七王固定用牌背
本节按 design §12.3 的阶段顺序走,每节说明**该阶段收哪些包、渲染什么、哪些 UI 显隐**。资源与精灵的完整表在 §3 / §5,本节只引用不重复。
```
建房(§1.1) → 发牌(§1.2) → 叫分坐庄(§1.3) → 看暗牌·上庄(§1.4) → 选主/投降(§1.5) → 埋牌(§1.6)
建房(§1.1) → 发牌(§1.2) → 叫分坐庄(§1.3) → 看底牌·上庄(§1.4) → 选主/投降(§1.5) → 埋牌(§1.6)
→ 出牌对局(§1.7) → 末轮扣底 + 小局结算(§1.8) → 大局结算(§1.9) → 解散(§1.10) → 重连(§1.11)
```
@@ -409,7 +425,7 @@ EQW_RoomOptions = {
| --- | --- |
| 底栏局数显示 `1/4 局` | §2.6 底栏 · 局数文字 |
| 自己手牌 28 张,按主牌顺序排序后铺开 | §2.7 手牌区(群组 210) |
| 桌面中央 8 张暗牌**背面** | 暗牌区(群组 211,帧 = 牌背 55) |
| 桌面中央 8 张底牌**背面** | 底牌区(群组 211,帧 = 牌背 55) |
| 顶部信息条清零:主 = 无、叫分 = 0、抓分 = 0 | §2.1 顶部信息条 |
| 三家玩家位状态文字清空,`主N/对N` 角标隐藏 | §2.2 玩家位附加标记 |
| 倒计时显示在 `seat` 对应的位置 | §2.4 倒计时 |
@@ -425,14 +441,14 @@ EQW_RoomOptions = {
| 状态 | 参考图 | 表现 |
| --- | --- | --- |
| 等待他家叫分 | `等待叫分.png` | 中央保持 8 张暗牌背面;倒计时数字显示在**当前叫分者**的位置旁;已叫分的玩家位显示金色 `60分` 大字,未叫的为空 |
| 等待他家叫分 | `等待叫分.png` | 中央保持 8 张底牌背面;倒计时数字显示在**当前叫分者**的位置旁;已叫分的玩家位显示金色 `60分` 大字,未叫的为空 |
| 轮到自己叫分 | `自己叫分.png` | 中央弹出**叫分面板**(14 档按钮,两行 × 7)+ `不叫` 按钮;顶部一条提示 `70分坐庄才可投降`;倒计时移到自己操作区 |
| 自己已叫、轮到下家 | `自己已经叫分轮到下家叫分.png` | 叫分面板收起,中央显示自己刚叫的 `50分` 金色大字;已表态的玩家位显示 `不叫` 白色大字 |
**叫分面板规格**(群组 220,号段 1600–1649):
- 14 档:`70 65 60 55 50 45 40 35 30 25 20 15 10 5`,两行 × 7(行1 = 70…40,行2 = 35…5)。
- 每档 4 个精灵:按钮底 + 分数文字 + 角标底 + **子数角标文字**。
- 每档 3 个精灵:按钮底(**含角标底,同一张图**)+ 分数数字精灵 + 角标子数文字精灵。
- 角标显示该档的 `multiple`,**随房间「爬坡」开关取值**(协议 §3):
- 常规算子:65→2、60→3、55→4、**50 及以下统一 →6**、70→2
- 爬坡:65→2、60→3、55→4、50→6、45→7、40→8、35→9、30→10、25→11、20→12、15→13、10→14、5→15、70→2
@@ -449,14 +465,25 @@ EQW_RoomOptions = {
>
> 反证:常规算子下 50/45/40 与 35…5 的 `multiple` 同为 6 子,但参考图里它们是两种颜色。
**灰色 = 已经叫过的分数**(不可再叫)。故按钮底与角标底各 **4 帧**:
**灰色 = 已经叫过的分数**(不可再叫)。**颜色只因「不可叫」变灰,不随子数档位变化。**
| 帧 | 按钮底 | 角标底 |
**按钮底与右上角角标(不含文字)画在同一张图上**,即一个精灵一帧就同时包含按钮底色和角标底色。共 **4 帧**:
| 帧 | 内容 |
| --- | --- |
| 1 | 浅黄按钮底 + 蓝角标底(高分档 70/65/60/55) |
| 2 | 金黄按钮底 + 绿角标底(中分档 50/45/40) |
| 3 | 橙按钮底 + 深橙角标底(低分档 35…5) |
| 4 | **灰按钮底 + 灰角标底(已叫过 / 不可选)** |
**两种数字,两种精灵**:
| 元素 | 精灵类型 | 说明 |
| --- | --- | --- |
| 1 | 浅黄(高分档) | 蓝 |
| 2 | 金黄(中分档) | 绿 |
| 3 | 橙(低分档) | 深橙 |
| 4 | **灰(已叫过 / 不可选)** | 灰 |
| **叫分的分数**(70/65/…/5) | **数字精灵**(图片多帧,资源 `NUM_CALL_SCORE`) | 带描边、需与图一致的美术字 |
| **角标的子数**(`2子`/`7子`…) | **文字精灵**(`SpriteManager.setText`) | 随爬坡开关动态变,值域 2–15,用文字精灵最省 |
故每档 **3 个精灵**:按钮底(含角标底)+ 分数数字精灵 + 角标文字精灵。
- 可选性规则(design §4.2,**由服务端权威 `currcall` 决定,前端只据其置灰、不自行推导规则**):
- 暂定庄家首叫:5–70 全部可选,**无 `不叫`**;
- 其后:只有**严格低于 `currcall`** 的档位可选,`不叫` 可选。
@@ -465,16 +492,16 @@ EQW_RoomOptions = {
**上方提示条** `70分坐庄才可投降`:静态文字条,仅在叫分面板展开时显示。
### 1.4 看暗牌 / 上庄 `shangzhuang` 【部分待设计】
### 1.4 看底牌 / 上庄 `shangzhuang` 【部分待设计】
**收包字段**:`seat`、`call`、`banker`、`grade`(庄家叫分)、`multiple`、`bottomcards`、`ancard3s`、`cards`、`countdown`、`touxiang`。
| 分支 | 条件 | 表现 |
| --- | --- | --- |
| 常规坐庄 | 无 `ancard3s` | 庄家收到 `bottomcards`(8 张)与 `cards`(36 张)→ 暗牌翻正面短暂展示后并入手牌;闲家**收不到** `bottomcards`,暗牌区直接收起 |
| **70 分坐庄** | `ancard3s === 1` | **全场三家都收到 `bottomcards`** → 8 张暗牌翻正面**向所有玩家亮 3 秒**(design §4/§7.1),3 秒后庄家摸入手牌、闲家侧收起 |
| 常规坐庄 | 无 `ancard3s` | 庄家收到 `bottomcards`(8 张)与 `cards`(36 张)→ 底牌翻正面短暂展示后并入手牌;闲家**收不到** `bottomcards`,底牌区直接收起 |
| **70 分坐庄** | `ancard3s === 1` | **全场三家都收到 `bottomcards`** → 8 张底牌翻正面**向所有玩家亮 3 秒**(design §4/§7.1),3 秒后庄家摸入手牌、闲家侧收起 |
- **70 分亮 3 秒** 【待设计】:需要一个覆盖提示(如「70 分坐庄 · 暗牌公示」标题 + 3 秒倒计时),图层 105 群组 230。
- **70 分亮 3 秒** 【待设计】:需要一个覆盖提示(如「70 分坐庄 · 底牌公示」标题 + 3 秒倒计时),图层 105 群组 230。
- 上庄后统一更新:顶部信息条 `叫分` 列 = `grade`、角标 = `multiple`;`banker` 对应玩家位显示 **`庄` 印章**(含底栏自己位)。
- 三处 `庄` 印章是三个独立精灵(左上 / 右上 / 底栏),按 `banker` 显隐其一。
- **重连不重放**:协议明确 70 分的 3 秒亮牌是上庄时的一次性事件,`deskinfo` 重连**不重放**——前端不得在重连时补播。
@@ -634,7 +661,7 @@ EQW_RoomOptions = {
**结算包三种来源**(协议 §14):正常出牌结算(`chupai` + `bottom` + `aset`)、投降结算(只 `aset`)、解散结算(见 §1.10,投递方式完全不同)。
**扣底表现**(`bottom` 分组,design §6.3):
- `cards`(8 张底牌)**恒有** → 底牌区(群组 215,资源 `CARD_FACE_S`)翻开展示,design §11 明确「牌局结束需要亮出底牌」;
- `cards`(8 张**埋牌底牌**)**恒有** → 埋牌底牌区(群组 215,资源 `CARD_FACE_S`)翻开展示,design §11 明确「牌局结束需要亮出底牌」;
- `multiple` / `grade1` / `grade2` **仅闲家扣底时才有** → 展示 `底牌 20 × 4` 之类的翻倍算式。
- 文案格式:`叫分{aset.multiple}子 底牌 {bottom.grade1}x{bottom.multiple}`——**`x` 后面是扣底倍数**(design §6.3:单张 ×1、主对 ×2、N 连对 ×2N)。参考图 `底牌 20x0` 即底牌有 20 分、扣底倍数 0(本局闲家未扣底)。
- 闲家未扣底时 `bottom` 只有 `cards`,`multiple`/`grade1`/`grade2` 都不下发 → 倍数位显示 **0**。
@@ -746,7 +773,7 @@ EQW_RoomOptions = {
**关键点**:
- `playproc.cards`(当前轮桌面上的牌)**两种查牌模式下都有** —— 否则后出的人无从跟牌;
- `pushlist`(往轮历史)与 `seatlist` **仅可查牌模式有** —— 不查牌模式下前端不得渲染出牌历史;
- 70 分的 3 秒亮暗牌**不重放**;
- 70 分的 3 秒亮底牌**不重放**;
- **验收判据**(前端 05 §6.2):任意时刻丢弃 `this.data`、仅凭最近一次服务端快照重画,界面必须完全一致。做不到即「前端私存了状态」或「服务端漏发了字段」,两者都要修。
### 1.12 准备 `zhunbei`
@@ -837,23 +864,28 @@ y≈648–720 深色条。左侧头像/昵称/分数由平台渲染(§0.2)
| `上一轮` | **上一轮**所有人出的牌 | 可查牌 + 出牌阶段 + 已打过至少一轮 |
| `出牌历史` | 所有人**出过的全部牌** | 可查牌 + 出牌阶段 |
| `明牌` | 另两家手中全部主牌的具体牌面 | 可查牌 + 出牌阶段 + **已报无主** |
| **`扣底`** | **庄家查看自己埋的 8 张底牌** | **仅庄家** + 已埋牌之后 |
| **`底牌`** | **发牌时桌面留下的 8 张暗牌** | 见下方可见性问题 S-3 |
| **`扣底`** | **埋牌底牌**:庄家埋下的 8 张 | **仅庄家** + 已埋牌之后 |
| **`底牌`** | **底牌**:发牌时没发给玩家、留在桌面的 8 张 | 庄家全程;闲家仅 70 分坐庄局(S-3) |
> ### ⚠️ 术语陷阱:底栏「底牌」按钮看的不是「底牌」
> ### 术语已统一:按钮名 = 术语名
>
> design 术语表:**暗牌** = 发牌时留在桌面的 8 张;**底牌** = 庄家埋牌时重新扣下的 8 张。两者是**不同批的牌,不通用、不互换**。
> **本项目采用修订后的术语**(2026-08-25 定,取代 design.md 原表述):
>
> 底栏按钮的命名恰好**与术语相反**:
> | 新术语 | 指哪 8 张 | design.md 原称 |
> | --- | --- | --- |
> | **底牌** | 发牌时**没有发给玩家**、留在桌面的 8 张 | ~~暗牌~~ |
> | **埋牌底牌** | 庄家埋牌时从手里扣下的 8 张 | ~~底牌~~ |
>
> | 按钮 | 实际展示 | design 术语 | 协议字段 |
> 改后底栏按钮**名实相符**:`底牌` 按钮看底牌、`扣底` 按钮看埋牌底牌,不再有命名倒挂。
>
> **但协议字段目前仍两批共用 `bottomcards`**,只靠「在哪个包」区分语义,仍是易错点:
>
> | 按钮 | 展示 | 当前协议字段 | 建议改名(S-4) |
> | --- | --- | --- | --- |
> | `扣底` | 庄家埋的 8 张 | **底牌** | `maipai.bottomcards` / `PushCards.bottomcards`(仅庄家)/ 结算 `bottom.cards` |
> | `底牌` | 发牌留桌的 8 张 | **暗牌** | `shangzhuang.bottomcards`(庄家恒有,闲家仅 70 分时有)/ `ChooseMain`·`BuryCards.bottomcards`(仅庄家) |
> | `底牌` | 底牌(发牌留桌 8 张) | `shangzhuang.bottomcards`(庄家恒有,闲家仅 70 分时有)、`ChooseMain`/`BuryCards.bottomcards`(仅庄家) | 保持 `bottomcards` |
> | `扣底` | 埋牌底牌(庄家埋的 8 张) | `maipai.bottomcards`、`PushCards.bottomcards`(仅庄家)、结算 `bottom.cards` | 改为 **`burycards`** |
>
> 更容易踩的是:协议里这**两批牌用了同一个字段名 `bottomcards`**,只靠「在哪个包/哪个阶段」区分语义。
>
> **实现要求**:前端内部一律用 `anCards`(暗牌)/ `diCards`(底牌)两个不同变量名,**不要跟着按钮文案命名**;取值时按所在包判断语义。已列入验收清单(§7.3)。
> **实现要求**:前端内部用 `bottomCards`(底牌)/ `buryCards`(埋牌底牌)两个变量名区分;在 S-4 落地前,取值时必须按**所在包**判断 `bottomcards` 的语义。已列入验收清单(§7.3)。
- 精灵:群组 205,号段 1040–1069(5 个按钮 × 2 精灵 = 10)。
@@ -864,7 +896,7 @@ y≈648–720 深色条。左侧头像/昵称/分数由平台渲染(§0.2)
| **单排**(叫分 / 出牌) | 最多 36 | y≈455–645,x≈35–1250,重叠排列 |
| **双排**(庄家埋牌) | 36(17 + 19) | 上排 y≈285–455,下排 y≈455–645 |
- 建 **36 个手牌精灵**(庄家摸暗牌后的上限),资源 `CARD_FACE_L`。
- 建 **36 个手牌精灵**(庄家摸底牌后的上限),资源 `CARD_FACE_L`。
- 张数少于 36 时隐藏多余精灵并重算间距。
- 选中态:牌**上浮**(Y 偏移),另可叠加选中标记。
- 牌上标记(`拖` 圆标、⭐、🔵)见 T-8。
@@ -881,9 +913,9 @@ y≈648–720 深色条。左侧头像/昵称/分数由平台渲染(§0.2)
| ID | 键名 | 用途 | 帧数 | 帧说明 | 单帧尺寸 | 整图 |
| --- | --- | --- | --- | --- | --- | --- |
| 501 | `CARD_FACE_L` | 手牌、暗牌 | **60** | 见 §0.4 帧表(10×6 通用排版) | 110 × 190 | 1100 × 1140 |
| 501 | `CARD_FACE_L` | 手牌、底牌 | **60** | 见 §0.4 帧表(10×6 通用排版) | 110 × 190 | 1100 × 1140 |
| 502 | `CARD_FACE_M` | 已出牌区 | **60** | 同上 | 90 × 155 | 900 × 930 |
| 503 | `CARD_FACE_S` | 结算底牌区 | **60** | 同上 | 50 × 70 | 500 × 420 |
| 503 | `CARD_FACE_S` | 结算埋牌底牌区 | **60** | 同上 | 50 × 70 | 500 × 420 |
### 3.2 花色图标
@@ -898,7 +930,7 @@ y≈648–720 深色条。左侧头像/昵称/分数由平台渲染(§0.2)
| ID | 键名 | 用途 | 帧数 | 帧说明 | 尺寸 |
| --- | --- | --- | --- | --- | --- |
| 531 | `BTN_CALL_SCORE` | 叫分档位按钮底 | 3 | 帧1=可选(亮黄) 帧2=不可选(灰) 帧3=高亮(橙)【T-6】 | 74 × 56 |
| 531 | `BTN_CALL_SCORE` | 叫分档位按钮底 **+ 右上角角标底(同一张图,不含文字)** | **4** | 帧1=浅黄+蓝角标(70/65/60/55) 帧2=金黄+绿角标(50/45/40) 帧3=橙+深橙角标(35…5) 帧4=**灰**(已叫过/不可选)。**颜色按档位位置固定,只因不可叫变灰** | 74 × 56 |
| 532 | `BTN_NO_CALL` | `不叫` | 1 | 蓝色渐变 | 184 × 57 |
| 533 | `BTN_SUIT_CHOOSE` | 选主花色按钮底 | 1 | 金黄底 | 128 × 55 |
| 534 | `BTN_SURRENDER` | `投降` | 1 | 金黄底 | 128 × 55 |
@@ -943,11 +975,13 @@ y≈648–720 深色条。左侧头像/昵称/分数由平台渲染(§0.2)
| ID | 键名 | 用途 | 帧数 | 帧说明 | 尺寸 |
| --- | --- | --- | --- | --- | --- |
| 631 | `NUM_COUNTDOWN` | 倒计时数字 | 10 | 帧1–10 = 0–9 | 44 × 60 |
| 635 | `NUM_CALL_SCORE` | **叫分档位的分数数字**(深棕描边美术字) | 10 | 帧1–10 = 0–9 | 30 × 40 |
| 632 | `NUM_RESULT_WIN` | 结算得分数字(赢,橙) | 12 | 帧1–10 = 0–9,帧11 = `+`,帧12 = `-` | 46 × 62 |
| 633 | `NUM_RESULT_LOSE` | 结算得分数字(输,蓝) | 12 | 同上 | 46 × 62 |
| 634 | `TXT_JUDGE` | 判定结果文字 | ≥5 | 帧1=大光 帧2=小光 帧3=过庄 帧4=升级 帧5=投降【待设计】 | 待定 |
> **数字一律用图片多帧精灵**(不用 `SpriteManager.setText`)——参考图里的数字都带描边与渐变,文字精灵做不出这种效果。故 631–634 全部需要出图。
> **带描边/渐变的美术字用图片多帧精灵**(倒计时、结算得分、叫分分数),文字精灵做不出这种效果——631–635 都要出图。
> **纯数据型小字用文字精灵**(`SpriteManager.setText`):叫分角标的子数(值域 2–15,随爬坡开关变)、`主N`/`对N` 角标、局数、亮牌统计等。
### 3.7 浮层与气泡
@@ -957,7 +991,7 @@ y≈648–720 深色条。左侧头像/昵称/分数由平台渲染(§0.2)
| 652 | `TXT_BAOZHU` | 「报无主」提示【待设计】 | 1 | 待定 | 待定 |
| 653 | `TXT_SHUAICUO` | 「甩错」提示【待设计】 | 1 | 待定 | 待定 |
| 654 | `TXT_GRADE_FLOAT` | 捡分飘字底(`20分` 金色) | 1 | 待定 | 待定 |
| 655 | `PANEL_ANCARD_3S` | 70 分暗牌公示 3 秒的标题/边框【待设计】 | 1 | 待定 | 待定 |
| 655 | `PANEL_BOTTOM_3S` | 70 分底牌公示 3 秒的标题/边框【待设计】 | 1 | 待定 | 待定 |
### 3.8 建房选项
@@ -1056,8 +1090,8 @@ design 与协议均**未定义任何音效**。以下是按牌类游戏常规推
| 群组 | 精灵 ID | 键名 | 类型 | 用途 | 资源 / 帧 |
| --- | --- | --- | --- | --- | --- |
| **211** 暗牌 | 1250–1257 | `DARK_CARD_1..8` | 图片 ×8 | 8 张暗牌;未揭示时帧 = 55 牌背,70 分公示 / 庄家查看时翻正面 | `CARD_FACE_L` |
| **215** 底牌 | 1258–1265 | `BOTTOM_CARD_1..8` | 图片 ×8 | 结算时亮出的底牌 | `CARD_FACE_S` |
| **211** 底牌 | 1250–1257 | `BOTTOM_CARD_1..8` | 图片 ×8 | 底牌(发牌留桌 8 张);未揭示时帧 = 55 牌背,70 分公示 / 庄家查看时翻正面 | `CARD_FACE_L` |
| **215** 埋牌底牌 | 1258–1265 | `BURY_CARD_1..8` | 图片 ×8 | 结算时亮出的埋牌底牌 | `CARD_FACE_S` |
| **212** 自己出牌 | 1300–1327 | `PLAY_SELF_1..28` | 图片 ×28 | 本轮打出的牌 | `CARD_FACE_M` |
| | 1328 | `PLAY_SELF_TYPE_BG` | 图片 | 牌型标签 | `LABEL_CARDTYPE` |
| | 1329 | `PLAY_SELF_TYPE_TEXT` | 文字 | 标签文案 | —— |
@@ -1071,9 +1105,9 @@ design 与协议均**未定义任何音效**。以下是按牌类游戏常规推
| **220** 叫分面板 | 1600 | `CALL_PANEL_BG` | 图片 | 面板底 | `PANEL_CALL_SCORE` |
| | 1601 | `CALL_HINT_BG` | 图片 | 提示条底 | `BAR_HINT_TOP` |
| | 1602 | `CALL_HINT_TEXT` | 文字 | `70分坐庄才可投降` | —— |
| | 1603–1616 | `CALL_BTN_1..14` | 图片 ×14 | 档位按钮底(70…5) | `BTN_CALL_SCORE` 帧1可选/帧2灰/帧3高亮 |
| | 1617–1630 | `CALL_BTN_TEXT_1..14` | 文字 ×14 | 档位分数 | —— |
| | 1631–1644 | `CALL_BTN_BADGE_1..14` | 文字 ×14 | 该档 `multiple` 子数角标 | —— |
| | 1603–1616 | `CALL_BTN_1..14` | 图片 ×14 | 档位按钮底(**含角标底**,70…5) | `BTN_CALL_SCORE` 帧1–3 按档位位置固定 / 帧4 灰 |
| | 1617–1630 | `CALL_BTN_NUM_1..14` | **图片(数字精灵)** ×14 | 档位分数(70…5) | `NUM_CALL_SCORE` |
| | 1631–1644 | `CALL_BTN_BADGE_1..14` | **文字** ×14 | 该档 `multiple` 子数(`2子`…`15子`),随爬坡开关变 | —— |
| | 1645 | `CALL_BTN_NONE` | 图片 | `不叫` | `BTN_NO_CALL` |
| | 1646 | `CALL_BTN_NONE_TEXT` | 文字 | —— | —— |
| **221** 选主面板 | 1650 | `MAIN_TITLE_BG` | 图片 | `亮主` 斜角条 | `BAR_CHOOSE_MAIN` |
@@ -1106,7 +1140,7 @@ design 与协议均**未定义任何音效**。以下是按牌类游戏常规推
| 1754 | `TXT_SHUAICUO` | 图片 | 甩错提示【待设计】 | `TXT_SHUAICUO` |
| 1755 | `GRADE_FLOAT_BG` | 图片 | 捡分飘字底 | `TXT_GRADE_FLOAT` |
| 1756 | `GRADE_FLOAT_TEXT` | 文字 | `20分` | —— |
| 1757 | `ANCARD_3S_PANEL` | 图片 | 70 分暗牌公示框【待设计】 | `PANEL_ANCARD_3S` |
| 1757 | `BOTTOM_3S_PANEL` | 图片 | 70 分底牌公示框【待设计】 | `PANEL_BOTTOM_3S` |
| 1758 | `ANCARD_3S_TEXT` | 文字 | 公示标题 + 3 秒倒计时 | —— |
### 5.6 Layer 302 · 小局结算(群组 240)
@@ -1173,7 +1207,7 @@ for (var i = 0; i < cards.length; i++) {
| **算奖牌型** | **复制** | 张数不定、无小上限,多数局用不满 |
| 自己手牌(36) | 预置 | 上限确定;需逐张选中上浮、独立动画与点击 |
| 已出牌区(28 × 3) | 预置 | 需叠压 z 序与出牌动画,逐张独立控制 |
| 暗牌(8)/ 底牌(8) | 预置 | 固定 8 张 |
| 底牌(8)/ 埋牌底牌(8) | 预置 | 固定 8 张 |
| 建房规则选项 | 预置 | 选项集固定(4 组 8 项),数量小 |
> 精灵段 1001–2999 有近 2000 个空位(§0.3),预置的 ID 开销不构成压力;复制只用在「数量真的不定」的地方,避免给每处都背上显式清理的负担。
@@ -1252,7 +1286,7 @@ for (var i = 0; i < cards.length; i++) {
#### `line` — 等距排列
数量可变但**间距固定**的一排(暗牌 8 张、底牌 8 张)。
数量可变但**间距固定**的一排(底牌 8 张、埋牌底牌 8 张)。
```js
{ kind: 'line', direction: 'horizontal',
@@ -1359,9 +1393,9 @@ PLAY_AREA: {
```js
CARD_SIZE: {
L: { w: 110, h: 190, res: 'CARD_FACE_L' }, // 手牌、暗牌、算奖牌
L: { w: 110, h: 190, res: 'CARD_FACE_L' }, // 手牌、底牌、算奖牌
M: { w: 90, h: 155, res: 'CARD_FACE_M' }, // 已出牌区
S: { w: 50, h: 70, res: 'CARD_FACE_S' } // 结算底牌
S: { w: 50, h: 70, res: 'CARD_FACE_S' } // 结算埋牌底牌
}
```
@@ -1419,8 +1453,8 @@ CARD_SIZE: {
| **自己手牌 · 单排** | `fan` | `anchorX:640 anchorY:455 maxWidth:1215 size:L spacingMax:0 spacingMin:-78 anchor:center overlapFrom:left`。36 张时算出 `spacing = 1215−110)/35 − 110 ≈ −78`,即每张露 32px,与参考图实测 33px 吻合 |
| **自己手牌 · 双排(埋牌)** | `fan` ×2 | 上排 `anchorX:644 anchorY:285 maxWidth:928 size:L spacingMin:-65`;下排 `anchorX:644 anchorY:455 maxWidth:928 size:L spacingMin:-65`。**分行策略:上排 `floor(n/2)`、下排 `ceil(n/2)`**(36 张 = 18/18)。参考图的 17/19 无规则依据,按 mock 处理 |
| 手牌 · 选中上浮 | —— | `selectedOffsetY: -40`(配置项,不写死) |
| **暗牌区** | `line` | `anchorX:655 anchorY:110 size:L spacing:-36 anchor:center`(8 张) |
| **底牌区(结算)** | `line` | `anchorX:640 anchorY:163 size:S spacing:2 anchor:center`(8 张) |
| **底牌区** | `line` | `anchorX:655 anchorY:110 size:L spacing:-36 anchor:center`(8 张) |
| **埋牌底牌区(结算)** | `line` | `anchorX:640 anchorY:163 size:S spacing:2 anchor:center`(8 张) |
| **已出牌区** | `fan` | 见 §6.2 的 `bySeat` 示例(三家共用 base,LEFT 镜像) |
| 已出牌 · 牌型标签 | `attach` | `target:该区首张牌, corner:bottomLeft, offsetX:0, offsetY:-24` |
| 已出牌 · 牌角 `庄`/`大` 标 | `attach` | `target:对应牌, corner:topRight, offsetX:-28, offsetY:0` |
@@ -1529,7 +1563,7 @@ codes/config/
| 编号 | 界面 | 所属 | 说明 |
| --- | --- | --- | --- |
| D-1▲ | 建房规则选项区 | §1.1 | 样式范式与内容已定(3 类别 / 4 选项组),缺二七王定稿与在 Layer 27 内的确切尺寸位置 |
| D-2 | 70 分暗牌公示(3 秒) | §1.4 | 全场可见的暗牌展示 + 倒计时 |
| D-2 | 70 分底牌公示(3 秒) | §1.4 | 全场可见的底牌展示 + 倒计时 |
| D-3 | 甩错提示 | §1.7 | 整套收回、只出最小一张的表现 |
| D-4 | 报无主提示 | §1.7 | 玩家主牌出空时的全场提示 |
| ~~D-5~~ | ~~踩 / 没分 / 有分 气泡与入口~~ | §1.7 | **已定**:入口 = 底栏三按钮(占庄标区);气泡 3×2 六帧、按头像相对位置选朝向 |
@@ -1540,7 +1574,7 @@ codes/config/
| D-10 | 解散结算 | §1.10 | 投票界面平台全包(Layer 420),只剩结算面板,可复用 D-9 |
| ~~D-11~~ | ~~准备标识~~ | §1.12 | **已定**:用平台准备标识,子游戏不做 |
| ~~D-12~~ | ~~左上家已出牌区~~ | §2.3 | **已定**:与右上家左右镜像 |
| **D-13** | **`扣底` 按钮的查看面板** | §2.6 | 新增:庄家查看自己埋的 8 张底牌;可与 `底牌`(看暗牌)复用同一个「8 张牌」展示面板,仅数据源不同 |
| **D-13** | **`扣底` 按钮的查看面板** | §2.6 | 庄家查看自己埋的 8 张**埋牌底牌**;可与 `底牌` 按钮复用同一个「8 张牌」展示面板,仅数据源不同 |
### 7.2 待确认的规格问题
@@ -1569,9 +1603,9 @@ codes/config/
| ~~T-13~~ | 结算两个小字 = `牌局分`(`grade_jf`) / `算奖分`(`grade_aw`) |
| ~~T-14~~ | 算奖明细走独立的**算奖牌型叠加层** |
| ~~T-15~~ | 准备标识**用平台的** |
| ~~T-16~~ | `抓分` 角标 = **当前抓分的倍数**;协议现无此字段 → **S-1** |
| ~~T-16~~ | `抓分` 角标 = **当前捡分对应判定倍率的实时预览**(大光×3/小光×2/过庄×1/升N级×N);协议现无此字段,需服务端随现有包下发 → **S-1** |
| ~~T-17~~ | 倒计时归零**停在 `0`** 不隐藏 |
| ~~T-18~~ | 底栏 5 按钮:`上一轮`/`出牌历史`/`明牌`/`扣底`(庄家看底牌)/`底牌`(**看暗牌**);**术语陷阱见 §2.6**;暗牌可见性 → **S-3** |
| ~~T-18~~ | 底栏 5 按钮:`上一轮`/`出牌历史`/`明牌`/`扣底`(看**埋牌底牌**)/`底牌`(看**底牌**);术语已统一见 §2.6;可见性按手册 → **S-3** |
| ~~T-19~~ | 数字**一律用图片多帧精灵**(参考图数字带描边渐变,文字精灵做不出),资源 631–634 全部要出 |
| ~~T-21~~ | 手牌单排 `spacingMin:-78`、双排 `-65`(§6.7) |
| ~~T-22~~ | 算奖叠加层:**全屏半透明遮罩本身即关闭热区,点击遮罩关闭**,不另设关闭钮 |
@@ -1610,7 +1644,7 @@ codes/config/
| 10 | `EQW_Layout` 与 `Game_Modify.PLAYER_INFO_LAYOUT` 的头像框坐标一致 | §6.11 |
| 11 | 丢弃 `this.data`、仅凭最近一次服务端快照重画,界面完全一致 | 前端 05 §6.2 |
| 12 | 所有布局参数都在配置文件里,业务代码无裸值 | §6 |
| 13 | **暗牌 / 底牌未写反**:`底牌` 按钮显示暗牌、`扣底` 按钮显示底牌;内部变量用 `anCards`/`diCards` 区分 | §2.6 术语陷阱 |
| 13 | **底牌 / 埋牌底牌未写反**:`底牌` 按钮显示底牌(发牌留桌)、`扣底` 按钮显示埋牌底牌;内部变量用 `bottomCards`/`buryCards` 区分;S-4 落地前按「所在包」判断 `bottomcards` 语义 | §2.6 |
| 14 | 叫分按钮配色按**档位位置**取(非按子数),已叫过的档位置灰 | §1.3 |
| 15 | 自己发的提示本地回显后,收到失败回包时能撤掉 | §1.7 |
@@ -1634,24 +1668,36 @@ codes/config/
以下 3 条来自本轮确认的需求,**当前协议/服务端不支持**,需在服务端补齐后前端才能实现。三条都要同步更新 `packet_protocol.md`。
#### S-1 · 「当前抓分的倍数」字段(对应 T-16)
#### S-1 · 「当前抓分的倍数」字段(对应 T-16)—— 语义已确认,待服务端实现
**需求**:顶部信息条 `抓分` 列的角标要显示「当前抓分的倍数」(参考图 `45 [1倍]`)。
**需求**:顶部信息条 `抓分` 列的角标显示「当前抓分的倍数」(参考图 `45 [1倍]`),且**牌局过程中可见并正确更新**。
**现状**:服务端**没有任何**下发此值的字段。`chupai1/2/3` 只带 `grade`(本轮闲家得分),倍数类字段(`aset.upgrade`、`bottom.multiple`)**都要到结算包才有**——出牌过程中前端拿不到。
**语义(已确认)**:**当前捡分对应的判定倍率的实时预览**——即「若此刻结束,是几倍」:
**建议实现**:服务端已有 `class.arith.js` 的 `get_upgrade(call, grade, q)`(返回带符号判定倍率:3 大光 / 2 小光 / 1 过庄 / −N 升 N 级),出牌过程中随时可算。在 `chupai1/2/3`(以及重连包 `PushCards`)里增加一个字段,例如:
| 字段 | 类型 | 说明 |
| 当前捡分 `grade` 相对叫分 `call` | 判定 | 倍率 |
| --- | --- | --- |
| `curmultiple` | 整数 | 按当前累计捡分实时算出的判定倍率绝对值,供顶部 `抓分` 角标显示 |
| `grade == 0` | 庄家:大光 | **×3** |
| `0 < grade < Q` | 庄家:小光 | **×2** |
| `Q ≤ grade < call` | 庄家:过庄 | **×1** |
| `grade ≥ call` | 闲家:升 N 级 | **×N** |
**需先确认语义**(本条尚未完全定死):角标要显示的到底是
(a)**当前捡分对应的判定倍率**(大光×3 / 小光×2 / 过庄×1 / 升N级×N)的实时预览——即「若现在结束是几倍」;还是
(b)别的口径。
按字面「当前抓分的倍数」以及 `get_upgrade` 现成可用,(a) 最可能。**确认 (a) 之后即可动工**。
(`Q` = 小光/过庄分界兼升级级距:常规算子固定 40,爬坡按叫分分段,见 design §7.2.0 / §7.3.2。)
> 前端**不得自算**这个值——判定倍率属服务端权威裁定(红线:服务器权威、前端只显示不自算)。
**现状**:服务端**没有任何**下发此值的字段。`chupai1/2/3` 只带 `grade`(本轮闲家得分),倍数类字段(`aset.upgrade`、`bottom.multiple`)**都要到结算包才有**。
**实现要求**:
1. 算法**已存在**:`class.arith.js` 的 `get_upgrade(call, grade, q)` 返回带符号判定倍率(3 大光 / 2 小光 / 1 过庄 / −N 升 N 级),出牌过程中随时可算。
2. **不新开推送包**——随现有包一起下发,避免多一条推送链路:
| 包 | 增加字段 | 类型 | 说明 |
| --- | --- | --- | --- |
| `chupai1` / `chupai2` / `chupai3` | `curmultiple` | 整数 | 按当前累计捡分实时算出的判定倍率**绝对值**(`Math.abs(get_upgrade(...))`) |
| `deskinfo.PushCards` | `curmultiple` | 整数 | 同上,供重连后立即正确显示 |
| `shangzhuang` | `curmultiple` | 整数 | 叫分刚定、`grade == 0` 时即为大光 ×3,需要一个初始值 |
3. 三家**同值**,可整表下发,不涉及泄露(`grade` 本来就是公开信息)。
4. 前端**不得自算**——判定倍率属服务端权威裁定(红线:服务器权威、前端只显示不自算)。
#### S-2 · 下发「应当选中的牌」(对应 T-10)
@@ -1675,39 +1721,47 @@ codes/config/
**不违反「请求包只带意图」**:方向是服务端 → 前端的建议,前端仍只回传 `cards`,合法性最终由服务端校验。
#### S-3 · 底栏「底牌」按钮的暗牌可见性(对应 T-18)⚠️ 与 design 冲突
#### S-3 · 底牌的可见性:按手册办(对应 T-18)—— 已定
**需求**:底栏 `底牌` 按钮让**所有人**查看发牌时的 8 张**暗牌**。
**结论:按 design 手册**,即前述方案 (a)。底栏 `底牌` 按钮只在**能合法看到底牌**时可用:
**冲突**:design §4 明确——
> **非 70 分坐庄**:桌面 8 张暗牌**只有庄家可见**,庄家查看后摸入手牌。
> **70 分坐庄**:摸暗牌之前先向所有玩家亮出 3 秒。
协议也与之一致:`shangzhuang.bottomcards` **庄家恒有、闲家仅 70 分坐庄时才有**;重连包 `ChooseMain` / `BuryCards` / `PushCards` 的 `bottomcards` 全部标注「**只有庄家有此属性**」。
**因此闲家在非 70 分局根本收不到暗牌数据,「所有人可查看」在当前协议下无法实现。** 且这属于服务端红线「**下发即泄露**——包到了客户端就能被抓包看到,『前端拿到但不渲染』不算防护」,不能靠前端自觉。
**需要在三种方案里选一个**:
| 方案 | 含义 | 影响 |
| --- | --- | --- |
| **(a) 限定可见范围**(推荐) | `底牌` 按钮只在**能合法看到暗牌**时可用:庄家全程可用;闲家**仅 70 分坐庄局**(已公示过)可用,其余局按钮置灰或不显示 | 协议无需改,只改前端显隐条件;不破坏 design |
| **(b) 局末开放** | 牌局结束后向所有人下发暗牌,`底牌` 按钮在结算阶段才可用 | 需在 `jiesuan` 包补暗牌字段;不影响对局中的信息对称 |
| **(c) 改规则** | 暗牌对所有人全程可见 | **与 design §4 直接冲突**,需先改 design;且削弱 70 分公示这条规则的意义 |
**在此确认前,前端按 (a) 实现**(最保守、不需要改服务端、不违反任何红线),并在代码里留注释指向本条。
---
## 附:本文与其他文档的关系
| 文档 | 关系 |
| 谁 | 何时可用 |
| --- | --- |
| `server/games/erqiwang/docs/design/design.md` | **玩法规则权威源**。本文引用其条款,不重新定义规则 |
| `server/games/erqiwang/docs/protocol/packet_protocol.md` | **协议字段权威源**。本文的「渲染什么」全部溯源到具体字段 |
| `docs/client/development-guide/` | **前端规范权威源**。ID 范围、组件范式、红线均以其为准 |
| `docs_dev/uiref/*.png` | 参考图,13 张(11 张牌桌态 + 叫分按钮面板 + 1 张建房**样式范式**,末者内容属他游戏、不可照抄) |
| `client/js/gameabc-framework/ui/AlignmentUtils.js` | **布局求解的框架能力**。§6 的配置参数名与其入参一一对应,配置可原样喂入 |
| `client/js/gameabc-framework/templates/*.template.js` | 常量文件写法蓝本。本清单落地为常量文件时按其格式 |
| 庄家 | **全程可用**(他本来就摸过这 8 张) |
| 闲家 | **仅 70 分坐庄局**可用(这 8 张已向全场公示过 3 秒);其余局**按钮不显示** |
依据 design §4:非 70 分坐庄时这 8 张**只有庄家可见**;协议也一致(`shangzhuang.bottomcards` 闲家仅 70 分时才有,重连包的同名字段标注「只有庄家有此属性」)。
**服务端无需改动**——现有下发面正好支持这条规则:闲家在非 70 分局本来就收不到数据,按钮不显示即可,不存在「拿到了但不渲染」的泄露风险(服务端红线:下发即泄露)。
#### S-4 · 拆分 `bottomcards` 字段名(新增)
**需求**:底牌与埋牌底牌是两批不同的牌,协议里却共用 `bottomcards`,只靠所在包区分语义——易错,需要拆开。
**建议改法**(与新术语对齐,`bottomcards` 留给字面意义相符的「底牌」):
| 包 / 分组 | 当前字段 | 实际含义 | 建议 |
| --- | --- | --- | --- |
| `shangzhuang` | `bottomcards` | **底牌**(发牌留桌 8 张) | 保持 `bottomcards` |
| `deskinfo.ChooseMain` | `bottomcards` | **底牌** | 保持 |
| `deskinfo.BuryCards` | `bottomcards` | **底牌** | 保持 |
| `maipai` | `bottomcards` | **埋牌底牌**(庄家埋的 8 张) | 改为 **`burycards`** |
| `deskinfo.PushCards` | `bottomcards` | **埋牌底牌** | 改为 **`burycards`** |
| 结算 `bottom` 分组 | `bottom.cards` | **埋牌底牌** | 分组名可一并改为 `bury`,或保持 `bottom.cards` 但在文档注明 |
**影响面**:`packet_protocol.md`、服务端 `mod.js` / `class.paiju.js` / `class.desk.js` 的组包处,以及尚未开工的前端。**前端未开工,现在改代价最小。**
#### S-5 · 同步 design.md 与 packet_protocol.md 的术语(新增)
术语变更(暗牌→**底牌**、底牌→**埋牌底牌**)目前**只在本文生效**。`design.md` 是玩法**唯一权威源**,`packet_protocol.md` 是协议权威源,两者仍用旧术语——**三份文档术语打架会直接违反 SSOT**。
需要同步修订的位置(初步):
| 文档 | 位置 |
| --- | --- |
| `design.md` | §1 术语约定表(「暗牌」「底牌」「埋牌」「扣底」四条);§4 开局与坐庄流程 3/5 步;§6.3 扣底;§7.1 70 分说明;§8 算奖快照;§9 查牌;§12.1 流程 4/6/8 步;§12.3 阶段速览 |
| `packet_protocol.md` | `shangzhuang` / `maipai` / `deskinfo` 各分组的 `bottomcards` 说明;结算 `bottom` 分组;与 S-4 的字段改名一并做 |
| 服务端代码 | 注释与变量名(非必须,但建议一并对齐) |
> **本文已先行采用新术语**,并在此显式记录差异,避免读者误以为 design.md 也已改。**建议尽快同步**,否则「底牌」一词在两份权威文档里指两批不同的牌,是最危险的那类不一致。