sam-gong-game

產品設計文件 (PDD)

PDD — 三公遊戲(Sam Gong 3-Card Poker)Client Design Document

<!-- SDLC Design Layer 4:Product Design Document (PDD) — Cocos Creator 3.8.x Frontend -->


1. Document Control

欄位內容
DOC-IDPDD-SAM-GONG-GAME-20260422
專案名稱三公遊戲(Sam Gong 3-Card Poker)即時多人線上平台
文件版本v0.2-draft
狀態DRAFT
作者Evans Tseng(由 /devsop-autodev STEP-05 自動生成)
日期2026-04-22
來源 PRDPRD-SAM-GONG-GAME-20260421 v0.14-draft
來源 BRDBRD-SAM-GONG-GAME-20260421 v0.12-draft
建立方式/devsop-autodev STEP-05 自動生成

Change Log

版本日期作者變更摘要
v0.1-draft2026-04-22/devsop-autodev STEP-05初稿;依 PRD v0.14-draft + BRD v0.12-draft 生成;涵蓋所有 SCR/CMP、動畫規格、色彩排版、i18n、無障礙、Cocos Creator 場景結構、PRD↔PDD 追溯矩陣
v0.2-draft2026-04-22STEP-06 Review (Exhaustive, 6 Rounds)92 項修正:動畫時長數學修正(三公1.0s/破產0.7s/結算0.5s),全16個畫面(SCR-001~016)線框圖完整,§6.8音效規格、§6.9莊家皇冠動畫、§6.0轉場表,i18n命名空間完整(room/tutorial/game/lobby/leaderboard),所有錯誤狀態設計(禁令/維護/中途離開/層級資格),PDD-Q7/Q9/Q11解決,結算邊界案例、防沉迷、重連、旁觀out-of-scope等

2. Design Principles

2.1 核心設計原則

#原則說明
P1Server-Authoritative Display(伺服器權威顯示)Client 端永遠不計算任何遊戲邏輯結果(牌值、比牌、結算、抽水);所有顯示資料均來自 Colyseus Room State 廣播或 REST API 回應。Client 是「啞渲染器(dumb renderer)」。
P2Mobile-First(行動裝置優先)以 Android 8.0+(2GB RAM)為基準裝置設計;最小支援螢幕寬度 375px(iPhone SE);iOS 14+ 相容。所有佈局優先確保手機端可用性,桌面端為延伸擴充。
P3Touch Target ≥ 44pt所有可互動 UI 元素(按鈕、卡片、捲動清單項目)最小觸控目標尺寸為 44×44pt,符合 Apple HIG 與 WCAG 無障礙標準。
P4Performance Budget(效能預算)基準裝置 ≥ 30fps;旗艦機型目標 ≥ 60fps(REQ-013)。動畫總時長 ≤ 3 秒(發牌+翻牌+結算合計)。首屏載入 ≤ 5 秒(4G,1MB/s)。
P5Pixel-Art First(像素風優先)v1.0 主美術風格為像素風(Pixel-art);賭場風格僅製作大廳主頁、牌局主畫面、結算畫面 A/B 測試素材(Beta 封測用,最終風格由 PM + Art Director 於 2026-07-21 前決定)。
P6零硬編碼字串所有顯示字串必須外部化至 locale/zh-TW.json;Client bundle 不得包含任何語言字串常數。
P7合規優先(Compliance-First)免責聲明、Cookie 橫幅、防沉迷彈窗、年齡驗證閘均為必要 UI 元素,不可在任何設定下被略過或隱藏。

2.2 架構邊界(Client 禁止事項)

本 PDD 所有 UI 元件均嚴格遵守以下約束:

單一房間限制 (Single Room Constraint):


3. Screen Inventory(畫面清單)

SCR-ID畫面名稱進入點離開點
SCR-001Splash / Loading(啟動畫面)App 啟動完成資源載入(Cookie Banner 以疊加層方式在載入期間顯示,非獨立跳轉)→ SCR-004。注意:SCR-003 Cookie Banner 以 Overlay 方式疊加於 SCR-001 載入畫面,不產生獨立跳轉;首次啟動時在載入期間自動顯示 Cookie Bottom Sheet。
SCR-002Age Gate — OTP Verification(年齡驗證)SCR-004 點擊「正式對戰」且 age_verified=falseOTP 驗證成功 → SCR-004;取消 → SCR-004(僅限教學模式)
SCR-003Cookie Consent Banner(Cookie 同意橫幅)首次 Web 載入同意/拒絕 → SCR-001 繼續載入 → SCR-004
SCR-004Main Lobby(主大廳)登入成功、結局返回、配對取消點擊廳別 → SCR-005;點擊教學 → SCR-008;點擊排行榜 → SCR-010;點擊每日任務 → SCR-014;點擊設定 → SCR-015;點擊帳號 → SCR-013
SCR-005Room Tier Selection(廳別選擇)SCR-004 → 點擊快速配對選擇廳別 → SCR-006;返回 → SCR-004
SCR-006Matchmaking Waiting(配對等待)SCR-005 → 廳別確認配對成功 → SCR-007;超時(90s)→ SCR-004;取消 → SCR-004
SCR-007Game Table(遊戲桌面,主遊戲畫面)SCR-006 配對成功;SCR-008 教學轉正式局結算完成 → SCR-009;主動離開 → SCR-004;斷線 → 重連恢復 SCR-007
SCR-008Tutorial(新手引導,3 輪固定劇本)SCR-004 → 點擊教學;首次登入自動觸發3 輪完成 → 引導完成頁 → SCR-004(解鎖正式對戰);跳過說明文字 → 繼續下一步
SCR-009Settlement Overlay(結算疊加層)SCR-007 → phase=settled 廣播計時器歸零或點擊「下一局」→ SCR-007(繼續)或 SCR-004(離開)
SCR-010Leaderboard(排行榜)SCR-004 → 排行榜圖示;SCR-007 → 排行榜圖示關閉 → 返回上一頁(SCR-004 或 SCR-007)
SCR-011Chat Panel(聊天面板,遊戲內疊加層)SCR-007 → 聊天圖示關閉 → 返回 SCR-007
SCR-012Anti-Addiction Popup(防沉迷彈窗)Server 訊號觸發:成人 2h 提醒;未成年 2h 硬性停止成人確認後繼續 → 返回觸發前畫面;未成年強制 → 登出 → SCR-004
SCR-013Profile / Account(個人資料 / 帳號)SCR-004 → 帳號圖示關閉 → SCR-004
SCR-014Daily Tasks & Chips Claim(每日任務與籌碼領取)SCR-004 → 每日任務圖示關閉 → SCR-004
SCR-015Settings(設定)SCR-004 → 設定齒輪;SCR-007 → 設定齒輪關閉 → 返回上一頁
SCR-016籌碼商店(Chip Store,v1.x 佔位)SCR-004 大廳「購買籌碼」按鈕 / SCR-013 充值入口關閉 → 返回上一頁

SCR-016 為 v1.x 佔位畫面(靜態免責聲明 + 「敬請期待」文字),實際購買功能實作依 2026-05-15 法律意見書決定。v1.0 僅顯示免責聲明:「本遊戲使用虛擬籌碼,不可兌換現金或任何形式之有價資產。」

旁觀模式 (Spectator Mode):


4. UI Component Library(UI 元件庫)

CMP-001:Card(撲克牌元件)

屬性規格
元件 IDCMP-001
元件名稱Card
尺寸64×96pt(標準);遊戲桌面縮小版:48×72pt
像素風格2px 黑色邊框;8px 圓角;像素點陣字體顯示牌面數字/花色

視覺狀態規格:

狀態視覺描述資源命名
面朝下(face-down)深藍色背面圖案(像素菱形紋);顯示背面圖示card_back.png
面朝上 — 數字牌(2–9)白色牌面(#FEFEFE);左上/右下角顯示點數 + 花色;中央大花色符號card_[suit]_[value].png
面朝上 — 人頭牌(10/J/Q/K)白色牌面;像素人物插圖;10/J/Q/K 字樣;此牌計分為 0 點card_[suit]_[face].png
面朝上 — A 牌白色牌面;大 A 字樣;計分為 1 點card_[suit]_a.png
三公高亮(Sam Gong)金色(#D4AF37)邊框光暈動畫;牌面正常顯示;Server 廣播 is_sam_gong=true 後觸發card_[suit]_[face].png + fx_sam_gong_glow.png(靜態光暈 Sprite,三公牌面疊加用;動畫版見 fx_sam_gong_glow.anim in §6.4)
禁用(disabled)灰階濾鏡(brightness 60%);棄牌(Fold)玩家的牌保持 face-down 不翻開

card_back.png 設計規格(供美術參考):

- 底色:#0D2137(深海藍)

- 菱形紋路顏色:#1E3A5F(較亮深藍),8px × 8px 重複 tile,45° 旋轉像素菱形

- 邊框:2px 寬 #D4AF37(金色)內嵌 4px,四角圓弧 4px

- 中央 Logo:16×16pt 像素藝術「三公」文字 mark,顏色 #D4AF37

- 整體風格:像素藝術(pixel art),與遊戲整體美術風格一致

花色顏色規格:

行為:


CMP-002:Chip Stack(籌碼堆疊元件)

屬性規格
元件 IDCMP-002
元件名稱Chip Stack
尺寸籌碼幣:32×32pt;堆疊最多 5 枚視覺堆疊(超過以數字標示)

籌碼面額顏色:

面額顏色資源
100白色 #FFFFFFchip_100.png
500橙色 #E67E22chip_500.png
1,000(1K)藍色 #2980B9chip_1000.png
5,000(5K)紫色 #8E44ADchip_5000.png
10,000(10K)綠色 #27AE60chip_10000.png
50,000(50K)深綠 #1A6B35chip_50000.png
100,000(100K)黑色 #2C3E50chip_100000.png
500,000(500K)深紅 #922B21chip_500000.png
1,000,000(1M)金色 #D4AF37chip_1000000.png

狀態:

大額面額顯示:

行為:


CMP-003:Player Avatar(玩家頭像元件)

屬性規格
元件 IDCMP-003
元件名稱Player Avatar
尺寸56×56pt(遊戲桌面);72×72pt(個人資料頁)
形狀圓形裁切;2px 邊框

狀態與視覺規格:

狀態邊框顏色疊加圖示說明
一般閒家#FFFFFF(白)預設狀態
莊家(Banker)#D4AF37(金)皇冠圖示 ic_crown.png(頭像右上角)Server banker_seat_index 對應座位
當前行動中#2980B9(藍)閃爍計時器倒數中
棄牌(Fold)#95A5A6(灰)「棄牌」文字標籤net_chips=0,顯示折疊圖示
斷線中#E74C3C(紅)虛線斷線圖示 ic_disconnect.pngisConnected=false
勝(Settlement)#27AE60(綠)光暈winners 陣列中
敗(Settlement)#C0392B(紅)光暈losers 陣列中
破產(Insolvency)#C0392B(紅)閃爍「破產!」標籤banker_insolvent=true
破產得零(insolvent_winner)#C0392B(紅)+ 紅色光暈頭像右上角「⚠ -{bet}籌碼損失」標籤(紅色背景)技術上贏牌但因莊家破產 payout=0、net_chips=-bet(實際損失,以紅色顯示)
載入中(Loading)#7F8C8D 灰色虛線圓框骨架佔位圖(Skeleton circle,直徑與頭像相同,灰色脈衝動畫)頭像圖片網路載入期間;圖片載入完成後無動畫直接切換

包含子元素:


CMP-004:Bet Slider / Input(下注滑桿 / 輸入元件)

屬性規格
元件 IDCMP-004
元件名稱Bet Slider / Input
尺寸寬度:100% 行動端寬度 - 32pt padding;高度:64pt

視覺規格:

快捷籌碼按鈕(可選):

狀態:

狀態視覺
Default滑桿可操作;顯示 min_bet
Active(拖曳中)拇指放大至 32×32pt;顯示即時金額
Disabled整體灰階;不可互動;莊家下注等待時閒家此元件 disabled
Loading按鈕顯示 spinner

行為:

下注金額驗證回饋 (Bet Validation Feedback):


CMP-005:Action Buttons(操作按鈕組)

屬性規格
元件 IDCMP-005
元件名稱Action Buttons(Call / Fold / See Cards)
按鈕尺寸最小 120×44pt(觸控目標 ≥ 44×44pt);圓角 8pt

Call 按鈕:

Fold 按鈕:

See Cards 按鈕(莊家查看手牌):

狀態:

狀態視覺觸發條件
Hiddenopacity=0width=0(不佔空間)banker-bet phase;或本地玩家非莊家
Appearfade-in 0.2s;從底部滑入 0.3sphase=banker-bet 且本地玩家為莊家
Active正常顯示phase=banker-bet 且本地玩家為莊家且尚未查看手牌
Disabled灰階;pointer-events=none莊家已執行 see_cards 或已完成 banker-bet 下注
Processing顯示 spinner;disabledsee_cards 訊息已發送,等待 Server myHand 回應

莊家 banker-bet 階段操作說明:

網路延遲回饋規格(Network Latency Feedback):

  1. 按鈕恢復 Active 狀態(可重新點擊)
  2. 顯示 Toast: errors.action_timeout(「操作逾時,請重試或檢查網路連線」)
  3. 計時器繼續正常倒數(不因 Client 逾時而停止,Server 有最終決定權)

CMP-006:Phase Indicator(階段指示器)

屬性規格
元件 IDCMP-006
元件名稱Phase Indicator
尺寸120×28pt;圓角 14pt

Phase 對應顯示:

Phase ENUM顯示文字(zh-TW)背景色備注
waiting等待玩家加入#7F8C8D(灰)一般等待狀態
dealing發牌中#2980B9(藍)
banker-bet莊家下注中#D4AF37(金)
player-bet玩家決策中#E67E22(橙)
showdown翻牌比較#8E44AD(紫)
settled結算完成#27AE60(綠)
等待中(有新莊家)白色/#FFFFFF 文字#7F8C8D(灰)game.phase.waiting_new_banker = "等待玩家加入,新莊家為:{player_name}"本局結算後(settled→waiting)顯示新莊家名稱

Phase Key 映射規則 (Phase-to-i18n Mapping):

Phase Enum → i18n Key 映射規則:

Room State phase 欄位使用連字號(hyphen)格式(如 banker-betplayer-bet),i18n key 使用底線(underscore)格式(如 game.phase.banker_betgame.phase.player_bet)。

映射公式:i18nKey = 'game.phase.' + phase.replace(/-/g, '_')

實作參考:

const phaseKey = `game.phase.${room.phase.replace(/-/g, '_')}`;
const phaseText = i18n.t(phaseKey); // e.g., '莊家下注中'

此規則適用於所有 CMP-006 Phase Indicator 文字渲染。


CMP-007:Timer Bar(倒數計時條)

屬性規格
元件 IDCMP-007
元件名稱Timer Bar
尺寸寬度:100%(操作區域寬度);高度:8pt

視覺規格:

行為:

狀態:


CMP-008:Settlement Card(結算資訊卡)

屬性規格
元件 IDCMP-008
元件名稱Settlement Card
尺寸寬度:100% 疊加層寬度;每行玩家高度:56pt

每行玩家結算顯示:

ties vs folders 牌面顯示區分(重要):

玩家類型來源陣列牌面狀態標籤文字net_chips 顯示
平手玩家(ties)settlement.ties面朝上(face-up),3 張牌可見「平手退注」灰色標籤(#7F8C8D0,灰色顯示
棄牌玩家(folders)settlement.folders面朝下(face-down),顯示牌背「棄牌」灰色標籤(#7F8C8D0,灰色顯示

注意:ties 與 folders 的 net_chips 均為 0,但牌面可見性完全不同:ties 玩家展示手牌(證明平手);folders 玩家保持暗牌(已棄牌者無需揭牌)。

特殊標籤:


CMP-009:Chat Bubble(聊天氣泡)

屬性規格
元件 IDCMP-009
元件名稱Chat Bubble
尺寸最小寬度 80pt;最大寬度 240pt;視覺氣泡最小高度 32pt;觸控熱區(Hit Area)擴展至 44×44pt(透過 Cocos Creator Widget 或 EventTarget hitTestTarget 實現,確保可觸控舉報時符合無障礙要求);圓角 12pt

視覺規格:

聊天面板(SCR-011):


CMP-010:Anti-Addiction Overlay(防沉迷疊加層)

屬性規格
元件 IDCMP-010
元件名稱Anti-Addiction Overlay
尺寸全螢幕疊加層;背景 rgba(0,0,0,0.85)

成人 2h 提醒版本(可繼續):

未成年 2h 強制停止版本(硬性停止):

未成年牌局中觸發(underage, mid-game):

成人 vs 未成年訊號區分:

訊號類型Server 訊息名稱Payload行為
成人 2h 提醒anti_addiction_warning{ type: "adult", session_minutes: 120 }顯示可繼續 popup;確認後重置計時器;2h 後再次觸發
未成年 2h 硬停anti_addiction_signal{ type: "underage", daily_minutes_remaining: 0, midnight_timestamp: number }牌局中顯示 banner;局後強制登出;每日 00:00(UTC+8)重置;midnight_timestamp 由 Server 計算(台灣時間次日 00:00 對應的 Unix ms);Client 以 midnight_timestamp - Date.now() 顯示倒數

救濟籌碼補發通知(Rescue Chips Notification):


CMP-012:Betting Panel(押注 / 跟注面板)

屬性規格
元件 IDCMP-012
元件名稱BettingPanelComponent(整合 CMP-004 + CMP-005 + 自動押注 Toggle + 3s 倒數進度條)
顯示條件phase === 'banker-bet'(莊家押注模式)或 phase === 'player-bet' 且本地玩家為當前輪次(跟注模式)

Auto-Act Toggle(自動押注 / 自動跟注):

狀態:

狀態視覺
DefaultToggle 未勾選;進度條隱藏
Checked(用戶主動勾選)Toggle 勾選;進度條顯示並開始 3s 倒數;倒數到 0 時自動執行 action
Cancelled(倒數中取消)點擊 Toggle 取消勾選 或 點擊「確認下注」/「跟注」手動送出 → 進度條隱藏;倒數計時器清除

5. Screen Wireframes(詳細佈局規格)

SCR-001:Splash / Loading

┌────────────────────────────────┐
│                                │
│                                │
│         [LOGO 256×256pt]       │
│       三公 Online              │
│       (像素風 Logo)             │
│                                │
│     ████████████░░░░  60%      │  ← 載入進度條(CMP 風格)
│     載入資源... (14pt灰色)       │
│                                │
│                                │
│  娛樂性質,虛擬籌碼無真實財務價值  │  ← 免責聲明(12pt 最小,REQ-013 AC-5)
└────────────────────────────────┘

SCR-002:Age Gate — OTP Verification

┌────────────────────────────────┐
│  ← 返回(僅教學模式可返回)       │
│                                │
│     年齡驗證                    │  ← 20pt 粗體
│                                │
│  請輸入您的出生年份:             │
│  ┌──────────────────────────┐  │
│  │  1 9 8 5        ▼        │  │  ← 年份選擇器(picker)
│  └──────────────────────────┘  │
│                                │
│  請輸入您的手機號碼:             │
│  ┌──────────────────────────┐  │
│  │  +886 0912-345-678       │  │
│  └──────────────────────────┘  │
│                                │
│  [      發送驗證碼      ]       │  ← 藍色按鈕
│                                │
│  ┌──────────────────────────┐  │
│  │  請輸入 6 位驗證碼:       │  │
│  │  [   ] [   ] [   ]       │  │
│  │  [   ] [   ] [   ]       │  │
│  └──────────────────────────┘  │
│  重送驗證碼 (60s 冷卻)           │
│                                │
│  [      確認驗證      ]         │  ← 綠色按鈕
│                                │
│  娛樂性質,虛擬籌碼無真實財務價值  │
└────────────────────────────────┘

流程說明(REQ-014 AC-3):

  1. 玩家輸入出生年份 → Server 驗算 currentYear - birthYear ≥ 18
  2. 通過 → 輸入手機號碼 → 發送 OTP(6 碼,5 分鐘有效)
  3. OTP 輸入 → 驗證成功 → age_verified=true → 返回 SCR-004
  4. OTP 錯誤 ≥ 3 次 → 顯示「驗證碼已失效,請重新發送」
  5. 每日 OTP 上限 5 次;超限顯示 errors.otp_daily_limit_exceeded

SCR-003:Cookie Consent Banner(Web 限定)

┌────────────────────────────────────────────────────┐
│ 🍪  我們使用 Cookie                                  │
│                                                      │
│ 本站使用 Cookie 提升您的使用體驗。請選擇您同意的類型:    │
│                                                      │
│ [✓] 必要性 Cookie(無法停用)                          │
│ [ ] 分析性 Cookie(可選)                              │
│ [ ] 行銷性 Cookie(可選)                              │
│                                                      │
│ [    僅接受必要性    ]    [    接受所選項目    ]         │
│                                                      │
│ 了解更多 | 隱私權政策                                   │
└────────────────────────────────────────────────────┘

SCR-004:Main Lobby(主大廳)

┌────────────────────────────────┐
│ [🏆排行榜]   三公Online  [⚙設定] │  ← 頂部導航列
│                                │
│ [頭像] 玩家暱稱     💎 鑽石廳   │  ← 玩家資訊列
│        籌碼:1,234,567          │
│                                │
│ ┌──────────────────────────┐   │
│ │  🎁 今日籌碼              │   │  ← 每日籌碼領取卡(REQ-020a)
│ │  領取今日籌碼 +5,000      │   │
│ │  [    立即領取    ]       │   │
│ └──────────────────────────┘   │
│                                │
│ 選擇對戰廳:                    │
│ ┌────────────┐ ┌────────────┐  │
│ │  🥉 青銅廳  │ │  🥈 白銀廳  │  │
│ │下注 100-500│ │下注 1K-5K  │  │
│ └────────────┘ └────────────┘  │
│ ┌────────────┐ ┌────────────┐  │
│ │  🥇 黃金廳  │ │  🏅 鉑金廳  │  │
│ │下注 10K-50K│ │下注 100K-500K│ │
│ └────────────┘ └────────────┘  │
│ ┌────────────┐                 │
│ │  💎 鑽石廳  │                 │
│ │下注 1M-5M  │                 │
│ └────────────┘                 │
│                                │
│ [新手引導] [每日任務] [排行榜]    │  ← 底部快捷列
│                                │
│ 娛樂性質,虛擬籌碼無真實財務價值  │
└────────────────────────────────┘

SCR-004 籌碼餘額資料來源:

廳別按鈕設計說明:


SCR-005:Room Tier Selection(廳別選擇)

┌────────────────────────────────┐
│ ←  選擇 青銅廳 模式              │
│                                │
│ ┌──────────────────────────┐   │
│ │  ⚡ 快速配對               │   │
│ │  系統自動配對相近等級對手    │   │
│ │  通常 ≤ 30 秒(取決於在線玩家數,高峰期可能更快)│
│ │  [    立即配對    ]        │   │
│ └──────────────────────────┘   │
│                                │
│ ┌──────────────────────────┐   │
│ │  🔑 私人房間               │   │
│ │  輸入房間 ID 或建立新房間   │   │
│ │  房間 ID:[____________]  │   │
│ │  [  加入  ]  [  建立  ]   │   │
│ └──────────────────────────┘   │
│                                │
│ 本廳規格:                      │
│   入場門檻:≥ 1,000 籌碼        │
│   下注範圍:100 – 500 籌碼      │
│   最多 6 人 / 最少 2 人         │
│                                │
│ 本遊戲為娛樂性質,虛擬籌碼       │  ← 免責聲明(12pt 最小,#7F8C8D,REQ-013 AC-5)
│ 無任何真實財務價值               │
└────────────────────────────────┘

行為規格補充(REQ-013 AC-5): 免責聲明文字「本遊戲為娛樂性質,虛擬籌碼無任何真實財務價值」須固定於 SCR-005 畫面底部,使用 12pt 最小字號,顏色 #7F8C8D,任何設定下不可隱藏。

私人房間建立/加入流程 (Private Room Flow)

建立私人房間:

  1. 點擊「建立房間」→ Server 建立房間並回傳 Room ID(格式:6 位大寫英數字,例:ABCD12
  2. 顯示「房間建立成功」Modal:
  1. Room ID 有效期:本局結束後自動失效

加入私人房間:

SCR-005 Error States(錯誤狀態)

錯誤情境顯示方式i18n Key說明
房間已滿Toast,顯示 3s 後消失errors.room_full「此房間已滿,請選擇其他房間」
無效房間 IDInline 紅色錯誤標籤,顯示於 Room ID 輸入欄下方errors.room_not_found「找不到此房間,請確認 ID 是否正確」
籌碼不足(Insufficient Chips)Toast(3s 自動消失)errors.insufficient_chips_for_tier'您的籌碼不足以進入此廳(需 {required} 籌碼,目前僅有 {current} 籌碼)'

SCR-006:Matchmaking Waiting(配對等待)

┌────────────────────────────────┐
│                                │
│      配對中...                  │
│                                │
│   ┌─────────────────────┐      │
│   │  🥉 青銅廳           │      │
│   │  100 – 500 籌碼     │      │
│   └─────────────────────┘      │
│                                │
│      [正在尋找對手...]           │  ← 像素動畫旋轉
│                                │
│   ████████████░░░░░░  00:24    │  ← 配對倒數條(90s 總上限)
│                                │
│   找到玩家:2 / 6               │  ← 已加入人數
│                                │
│   ┌─────────────────────────┐  │
│   │ ⚡ 擴大配對中(+{adjacent_tiers})│  │  ← 超過 30s 後顯示
│   └─────────────────────────┘  │
│                                │
│      [    取消配對    ]         │
│                                │
│ 本遊戲為娛樂性質,虛擬籌碼       │  ← 免責聲明(12pt 最小,#7F8C8D,REQ-013 AC-5)
│ 無任何真實財務價值               │
└────────────────────────────────┘

行為規格補充(REQ-013 AC-5): 免責聲明文字「本遊戲為娛樂性質,虛擬籌碼無任何真實財務價值」須固定於 SCR-006 畫面底部,使用 12pt 最小字號,顏色 #7F8C8D,配對進行中不可隱藏。

行為規格:


私人房間等待模式(Private Room Host Waiting Mode)

SCR-006 有兩種模式,由 room_type 參數決定:

模式A:一般配對(Matchmaking)— 現有設計(room_type=matchmaking

模式B:私人房間等待(Private Room Waiting,room_type=private

┌──────────────────────────────────────────────────┐
│  ← 返回                         房間等待中        │
│                                                   │
│  您的房間 ID                                       │
│  ┌──────────────────────────────────────────────┐ │
│  │     ABCD12     [複製 ID]  [分享]              │ │
│  └──────────────────────────────────────────────┘ │
│                                                   │
│  玩家 (1/6)                                       │
│  ● 您(莊家)  [已就緒]                            │
│  ○ 等待中...                                      │
│  ○ 等待中...                                      │
│                                                   │
│  等待玩家加入...                                   │
│  [          開始遊戲(最少2人)          ]          │
│                                                   │
│ 本遊戲為娛樂性質,虛擬籌碼無任何真實財務價值         │
└──────────────────────────────────────────────────┘

SCR-007:Game Table(遊戲桌面)— 最核心畫面

┌────────────────────────────────────┐
│ [🏆]   三公 Online    [💬] [⚙]     │  ← 頂部列(排行榜/聊天/設定)
│                                    │
│   [P2 頭像]  [P3 頭像]  [P4 頭像]   │  ← 上方座位(對面玩家)
│   [🂠][🂠][🂠][🂠][🂠][🂠][🂠][🂠][🂠]│  ← 各玩家牌區(3張暗牌)
│                                    │
│ [P1]       ╭───────────────╮   [P5]│
│            │   底池: 0     │       │  ← 橢圓桌面(像素綠色 #1A6B35)
│  [🂠][🂠][🂠]│  抽水: 0      │[🂠][🂠][🂠]│
│            │  [CMP-006]    │       │
│            │  banker-bet   │       │
│            ╰───────────────╯       │
│                                    │
│   [P6 頭像 - 莊家 👑]              │  ← 莊家(top center,金色邊框)
│   [🂠][🂠][🂠]                       │
│                                    │
│ ────────────────────────────────── │
│   [我的頭像]   籌碼:12,345         │  ← 本玩家資訊列
│                                    │
│   [  ████████████████  ] 00:28     │  ← CMP-007 計時條
│                                    │
│   [    跟注 500    ]  [  棄牌  ]    │  ← CMP-005(player-bet phase 時顯示)
│   ┌─────────────────────────────┐  │
│   │ ●─────────────────── 下注  │  │  ← CMP-004(banker-bet phase 時顯示)
│   └─────────────────────────────┘  │
│                                    │
│  娛樂性質,虛擬籌碼無真實財務價值    │
└────────────────────────────────────┘

6 人桌位配置(順時鐘):

座位位置圖(邏輯座標):

        [座位3] [座位4]
   [座位2]  ╭──────────╮  [座位5]
            │  TABLE   │
   [座位1]  ╰──────────╯  [座位6]
        [本玩家/座位0]
座位邏輯畫面位置備注
本玩家(P0)畫面底部中央主要操作區;永遠是 P0 視角
P1畫面左側中
P2畫面左上
P3畫面上方中央莊家通常顯示於此(視輪莊動態)
P4畫面右上
P5畫面右側中

牌局元素佈局:

席位序號標示 (Seat Index Badge):

底池 / 抽水顯示時序邏輯:

  1. waiting / dealing phase:底池 = 0、抽水 = 0(重置顯示)
  2. banker-bet / player-bet phase:底池隨玩家下注實時更新(來自 Server Room State 廣播)
  3. showdown phase:顯示最終底池值(不再更新)
  4. settled phase:Settlement overlay 覆蓋後,底部數值更新為本局最終抽水額(來自 settlement.rake_amount

籌碼餘額顯示來源 (Chip Balance Data Source)

SCR-007 底部玩家資訊列中的「籌碼:N」來源:

  1. 進房時:從 Colyseus Room State players[self_seat_index].chip_balance 初始化
  2. 即時更新:監聽 Room State onChange 事件,chip_balance 欄位變更時立即更新顯示
  3. 斷線重連期間:顯示最後已知值,加灰色覆蓋層(opacity 0.5)表示數據可能過期
  4. 結算後:Room State 廣播 settlement 結果,chip_balance 更新後移除灰色覆蓋層

底部操作區(互斥顯示):

【banker-bet phase 底部操作區】

【player-bet phase 底部操作區(輪到本玩家)】

注意:以上兩個操作區在任意時間點只有一個 active;非本玩家回合時(他人操作中)兩者均隱藏;waiting / dealing / showdown / settled phase 時兩者均隱藏。


主動離開遊戲流程 (Intentional Leave Flow)

主動離開遊戲(Mid-Game Leave):

  ┌──────────────────────────────────────────────────┐
  │  確定要離開本局?                                   │
  │  ● 離開後,本局視同棄牌                             │
  │  ● 若本局已下注,將損失對應籌碼                      │
  │  [  取消(繼續遊戲)  ]  [  確定離開(紅色)  ]       │
  └──────────────────────────────────────────────────┘

i18n key: errors.leave_mid_game_confirm = '離開後視同棄牌,本局已下注籌碼將損失。確定離開嗎?'


SCR-007 Error States(錯誤狀態)

錯誤情境顯示方式i18n Key後續行為
被踢出房間全螢幕 Overlay,含確認按鈕errors.kicked_from_room點擊確認 → 導向 SCR-004
JWT Token 過期自動嘗試 Token Refresh;失敗則 Toast + 跳轉登入errors.session_expiredRefresh 失敗 → 導向 SCR-001(登入頁)
伺服器錯誤Toast,3s 自動消失errors.server_error「伺服器發生錯誤,請稍後再試」
帳號封禁(Banned)全螢幕 Overlay(無重試按鈕);顯示「您的帳號已被封禁」+ 客服聯絡超連結errors.account_bannedTerminal 狀態;無確認→返回大廳流程;封禁為本次 Session 終止狀態
伺服器維護(Maintenance)全螢幕 Overlay(無重試按鈕);顯示「伺服器維護中」+ 預計恢復時間(來自 Server payload {time})+ 倒數計時器errors.server_maintenance無 重試 按鈕,直至維護結束;Server 回傳 503 或 maintenance payload 時觸發

SCR-007 斷線重連狀態(P0 自身斷線)

觸發: Colyseus Client 偵測到連線中斷(onLeave / WebSocket 關閉事件)

視覺狀態設計:

(1) 斷線偵測後立即顯示:

┌────────────────────────────────┐
│ ░░░░░░░░░ [遊戲畫面] ░░░░░░░░░ │  ← 半透明黑色 overlay(rgba(0,0,0,0.75))
│                                │
│     連線中斷                    │
│     正在重新連線...              │
│     (嘗試 1/3)                │
│                                │
│          [●] spinner           │
│                                │
└────────────────────────────────┘

(2) 重連成功: overlay 淡出消失(0.3s fade-out);遊戲繼續,Room State 自動同步恢復

重連成功後狀態還原步驟:

  1. cc.game.on(cc.Game.EVENT_RESUME, ...) 或 Colyseus client.reconnect(roomId, sessionId) 觸發重連
  2. Colyseus 自動發送完整 Room State patch 至 Client
  3. 若 phase 為 dealing/banker-bet/player-bet(且本玩家已收過 myHand):
  1. 若 phase 為 showdown:所有已揭示的牌從 Room State 中的 revealed_cards 欄位還原為 face-up
  2. 計時器:從 action_deadline_timestamp - Date.now() 重新計算剩餘時間並恢復倒數
  3. Overlay 淡出後,所有遊戲 UI 元素(CMP-001~010)從 Room State 重新渲染

(3) 30 秒超時 / 3 次重連失敗:

┌────────────────────────────────┐
│                                │
│     重連失敗                    │
│                                │
│  若您在下注前斷線:              │
│  已自動棄牌(Server 代為執行)   │
│                                │
│  若您已完成下注:               │
│  下注已保留,結算結果將記錄      │
│                                │
│  [    返回大廳    ]             │
│                                │
└────────────────────────────────┘

SCR-008:Tutorial(新手引導)

步驟 1a:規則說明

┌────────────────────────────────┐
│  新手引導(1/5)   [跳過說明 ×] │
│                                │
│  三公規則說明                   │
│                                │
│  [規則說明圖示 + 文字]           │
│  • 3 張牌,點數加總 mod 10      │
│  • 三公 = 3 張花牌(10/J/Q/K,各計 10 點,合計 mod10 = 0,最高手牌)  │
│  • 比大小規則...               │
│                                │
│  [    下一步    ]               │
│  娛樂性質,虛擬籌碼無真實財務價值                 │
└────────────────────────────────┘

步驟 1b:籌碼系統說明

┌────────────────────────────────┐
│  新手引導(2/5)   [跳過說明 ×] │
│                                │
│  籌碼系統說明                   │
│                                │
│  廳別進場門檻:                  │
│  🥉 青銅廳  ≥ 1,000 籌碼       │
│  🥈 白銀廳  ≥ 10,000 籌碼      │
│  🥇 黃金廳  ≥ 100,000 籌碼     │
│  🏅 鉑金廳  ≥ 1,000,000 籌碼   │
│  💎 鑽石廳  ≥ 10,000,000 籌碼  │
│                                │
│  每日免費籌碼:每日 00:00(UTC+8)│
│  自動發放;籌碼 < 1,000 可領取  │
│  救濟籌碼(系統自動補發 1,000)  │
│                                │
│  [    下一步    ]               │
│  娛樂性質,虛擬籌碼無真實財務價值                 │
└────────────────────────────────┘

步驟 3–5(進度 3/5、4/5、5/5):3 輪模擬牌局

教學完成頁:

┌────────────────────────────────┐
│                                │
│     🎉 教學完成!               │
│                                │
│  您已學會三公基本規則            │
│  現在可以開始正式對戰!          │
│                                │
│  [    進入大廳    ]             │
│                                │
│  娛樂性質,虛擬籌碼無真實財務價值 │
└────────────────────────────────┘

進度指示器規格:


Tutorial 籌碼模擬規格(Tutorial Chip Display)

Tutorial 籌碼顯示行為:


Tutorial Script 固定腳本

設計說明:以下固定腳本中的牌值計算(如「15 mod 10 = 5」)為設計文件說明用途,代表 Server 側 Tutorial 腳本的固定設定值。Client 不執行任何點數計算,所有結果由 Server 確認後廣播。

欄位第 1 輪(3/5)第 2 輪(4/5)第 3 輪(5/5)
P0 手牌♠K / ♥Q / ♣J = 三公(0 點,最高)♠5 / ♥4 / ♣6 = 15 mod 10 = 5 點♠5 / ♥A / ♣K = 5+1+10=16 mod 10 = 6 點
NPC 手牌♦4 / ♣2 / ♥A = 4+2+1 = 7 點♦2 / ♣A / ♥K = 2+1+10=13 mod 10 = 3 點♦5 / ♣A / ♥K = 5+1+10=16 mod 10 = 6 點
莊家P0(教學中 P0 固定為莊家)P0P0
莊家下注100 籌碼100 籌碼100 籌碼
NPC 下注100 籌碼(跟注)100 籌碼(跟注)100 籌碼(跟注)
結算P0 勝(三公最高),獲得 100 籌碼淨利P0 勝(5 > 3),獲得 100 籌碼淨利平手(tutorial_force_tie: true),雙方退注,net_chips = 0
重點教學三公介紹(3 張花牌 = 最高手牌)普通點數比較規則雙方同分平手概念:當雙方點數相同且平局條件成立,視為平手,雙方退注(net_chips=0)
Tooltip i18n keystutorial.round1.introtutorial.round1.sam_gong_explaintutorial.round1.wintutorial.round2.points_explaintutorial.round2.wintutorial.round3.tie_concepttutorial.round3.result_tie

第 3 輪說明: 兩方均為 6 點,教學系統設定 tutorial_force_tie: true,強制觸發平手結算結果(net_chips=0,雙方退注)。本輪重點為展示平手退注概念,narration 說明「當雙方點數相同時,系統會進行加時比牌(D8);在極少數情況下仍會平局,此時雙方退注。」不逐步說明 D8 兩步驟,因實際手牌不產生真正的 D8 兩步驟均相同結果。此為固定劇本示範。

>

教學設計說明: R3 使用 tutorial_force_tie=true 展示平手結算結果。實際遊戲中平手極為罕見(需要D8兩步驟均相同)。教學不聲稱示範「D8 兩步驟均相同」,僅展示平手退注的結算概念。


SCR-009:Settlement Overlay(結算疊加層)

┌────────────────────────────────┐
│              結算              │  ← 20pt 粗體;居中
│                                │
│ ┌──────────────────────────┐   │
│ │ 👑 [莊家頭像] 莊家暱稱    │   │  ← 莊家行(置頂)
│ │ [🂡][🂡][🂡] 8 點         │   │
│ │                    +0    │   │  ← 或 破產!標籤
│ └──────────────────────────┘   │
│                                │
│ ┌──────────────────────────┐   │
│ │ [頭像1] P1 玩家           │   │
│ │ [♠K][♥Q][♣J] 三公!      │   │
│ │                  +1,500  │   │  ← 綠色 +N 動畫
│ └──────────────────────────┘   │
│ ┌──────────────────────────┐   │
│ │ [頭像2] P2 玩家           │   │
│ │ [🂠][🂠][🂠] 棄牌          │   │
│ │                     ±0   │   │  ← 灰色棄牌標籤
│ └──────────────────────────┘   │
│ ┌──────────────────────────┐   │
│ │ [頭像3] 我               │   │
│ │ [♦7][♣5][♥3] 5 點        │   │
│ │                  -500    │   │  ← 紅色 -N 動畫
│ └──────────────────────────┘   │
│                                │
│ 本局抽水:25 籌碼               │  ← 灰色小字
│                                │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━   │
│                                │
│ [    繼續下一局    ]  倒數 5s   │  ← 自動倒數後進入下一局
│ [    返回大廳    ]              │
└────────────────────────────────┘

莊家破產通知(banker_insolvent=true):

莊家籌碼餘額更新:

全員棄牌場景(All-Fold)特殊處理:

顯示規格:


SCR-010:Leaderboard(排行榜)

┌────────────────────────────────┐
│ ←  排行榜                       │
│                                │
│  [  週榜  ] [  籌碼榜  ]        │  ← 切換 Tab
│                                │
│  本週淨籌碼收益排名              │
│  更新時間:2026-04-22 14:30    │
│                                │
│ ┌────────────────────────────┐ │
│ │ #1  [頭像] 林小姐  💎        │ │
│ │     +12,450,000 籌碼       │ │
│ └────────────────────────────┘ │
│ ┌────────────────────────────┐ │
│ │ #2  [頭像] 張先生  🥇        │ │
│ │     +9,820,000 籌碼        │ │
│ └────────────────────────────┘ │
│  ...(無限滾動,初始 Top 20)    │
│                                │
│ ┌────────────────────────────┐ │
│ │ 我的排名:#47               │ │  ← 底部固定;未上榜時顯示 leaderboard.my_rank_unranked
│ │ +345,000 籌碼               │ │
│ └────────────────────────────┘ │
│                                │
│ 娛樂性質,虛擬籌碼無真實財務價值  │
└────────────────────────────────┘

排行榜資料規格:


SCR-013:Profile / Account(個人資料 / 帳號)

┌────────────────────────────────┐
│ ←  個人資料                     │
│                                │
│ ┌──────────────────────────┐   │
│ │  [頭像 72×72pt]           │   │  ← 圓形頭像
│ │  玩家暱稱(最多 8 字元)    │   │
│ │  ID:#12345678             │   │
│ └──────────────────────────┘   │
│                                │
│  今日已遊玩時間:1 小時 23 分鐘  │  ← REQ-015 AC-4(每日遊玩時間顯示)
│                                │
│ ┌──────────────────────────┐   │
│ │  帳號設定                 │   │
│ │  > 修改暱稱               │   │
│ │  > 更換頭像               │   │
│ └──────────────────────────┘   │
│                                │
│ ┌──────────────────────────┐   │
│ │  [    申請刪除帳號    ]   │   │  ← REQ-019;顯示確認對話框
│ └──────────────────────────┘   │
│                                │
│ 娛樂性質,虛擬籌碼無真實財務價值  │  ← 免責聲明
└────────────────────────────────┘

行為規格:


SCR-014:Daily Tasks & Chips Claim(每日任務與籌碼領取)

┌────────────────────────────────┐
│ ←  每日任務                     │
│                                │
│ ┌──────────────────────────┐   │
│ │  🎁 每日免費籌碼           │   │
│ │  今日可領:+5,000 籌碼    │   │
│ │  [    立即領取    ]        │   │  ← 已領取則顯示「明日 00:00 重置」
│ └──────────────────────────┘   │
│                                │
│  每日任務                       │
│ ┌──────────────────────────┐   │
│ │ [ ] 完成 1 局遊戲  +200  │   │
│ │ [✓] 登入遊戲      +100  │   │  ← 已完成打勾
│ │ [ ] 擔任莊家 1 次  +500  │   │
│ └──────────────────────────┘   │
│                                │
│                                │
│ 娛樂性質,虛擬籌碼無真實財務價值  │  ← 免責聲明
└────────────────────────────────┘

任務獎勵彈窗(task_reward_popup):

┌────────────────────────────────┐
│          任務完成!              │
│                                │
│  [✓ 動畫]  完成 1 局遊戲        │
│  獎勵:+200 籌碼               │
│                                │
│  娛樂性質,虛擬籌碼無真實財務價值 │  ← 免責聲明(REQ-013 AC-5,必須包含)
│                                │
│  [    確認    ]                 │
└────────────────────────────────┘

行為規格:

每週任務 Tab(v1.x 預留):


SCR-011:Chat Panel(聊天面板)

┌────────────────────────────────────┐
│  聊天                    [× 關閉]   │  ← 頂部標題列;[× 關閉] 按鈕 44×44pt
├────────────────────────────────────┤
│                                    │
│  ┌──────────────────────────────┐  │
│  │ 張先生(金色 10pt)           │  │  ← 他人訊息(左對齊)
│  │ 好牌!                       │  │
│  └──────────────────────────────┘  │
│                                    │
│              ┌─────────────────┐   │
│              │ 我(金色 10pt) │   │  ← 自身訊息(右對齊)
│              │ 謝謝!          │   │
│              └─────────────────┘   │
│                                    │
│  ┌──────────────────────────────┐  │
│  │ 林小姐(金色 10pt)           │  │
│  │ 這局真刺激                   │  │  ← 訊息列表區(可滾動,高度 = 面板高 - 頂部列 - 輸入區)
│  └──────────────────────────────┘  │
│                                    │
│   ┌──────────────┐  [⚑ 舉報]      │  ← 長按氣泡可舉報(44×44pt 熱區)
│   │ 訊息...      │                 │
│   └──────────────┘                 │
│                                    │
├────────────────────────────────────┤
│ ┌──────────────────────┐ [  發送 ] │  ← 底部輸入列(固定)
│ │ 輸入訊息(最多200字)  │ 48×44pt  │  ← 輸入框 44pt 高;發送按鈕 48×44pt;背景 #2980B9
│ └──────────────────────┘           │
└────────────────────────────────────┘

佈局規格:

聊天範圍與生命週期:

內容過濾回饋(Content Filter Feedback):

訊息被伺服器拒絕(內容過濾)時:

  1. 訊息出現在聊天列表
  2. Input field 下方顯示紅色 inline 錯誤標籤(i18n: errors.chat_content_filtered
  3. 訊息文字保留在 Input field 中(不清除,讓用戶可編輯修改)
  4. 錯誤標籤在用戶重新輸入或刪除字元後自動消失

SCR-011 Report Flow(舉報流程)

  1. 長按訊息氣泡 → Bottom Sheet 出現(0.2s slide up),包含:
  1. 點擊「舉報此訊息」 → 舉報原因選擇器(單選):
  1. 確認按鈕 → 送出 report_player { target_id: string, message_id: string, reason: string } 至 Server
  2. 成功:Toast chat.report_success(「舉報已提交,謝謝您的回報」)
  3. 失敗:Toast errors.server_error
  4. Emoji picker:v2.0 deferred(不在 v1.0 scope);Quick-phrase 按鈕:v2.0 deferred

SCR-012:Anti-Addiction Popup(防沉迷彈窗)

版本 A:成人 2 小時重複提醒(可繼續遊戲)

┌────────────────────────────────────┐
│ ░░░░░ [遊戲畫面(模糊)] ░░░░░░░░ │  ← 全螢幕半透明黑色 overlay rgba(0,0,0,0.85)
│                                    │
│   ╔══════════════════════════╗     │
│   ║      ⏰ 注意健康          ║     │  ← 標題 20pt 粗體;#FFFFFF
│   ╠══════════════════════════╣     │
│   ║                          ║     │
│   ║  您已連續遊玩 120 分鐘,    ║     │  ← 內容文字 14pt;#FFFFFF(anti_addiction.adult_warning)
│   ║  請適度休息,注意健康。     ║     │
│   ║                          ║     │
│   ║  本次提醒後計時重置,       ║     │  ← 2h 冷卻說明(灰色 12pt)
│   ║  下次提醒將在2小時後再次    ║     │
│   ║  出現。                   ║     │
│   ║                          ║     │
│   ║  [ 我知道了,繼續遊戲  ]   ║     │  ← 確認按鈕;背景 #2980B9;高度 44pt
│   ║                          ║     │
│   ╚══════════════════════════╝     │
│                                    │
│  (不可點擊背景遮罩關閉;必須點確認)  │
└────────────────────────────────────┘

成人版行為規格:


版本 B:未成年每日 2 小時硬性停止(遊戲鎖定)

┌────────────────────────────────────┐
│ ░░░░░ [遊戲畫面(已鎖定)] ░░░░░ │  ← 全螢幕半透明黑色 overlay rgba(0,0,0,0.92)
│                                    │
│   ╔══════════════════════════╗     │
│   ║  🚫 今日遊戲時間已達上限   ║     │  ← 標題 20pt 粗體;#C0392B(紅)
│   ╠══════════════════════════╣     │
│   ║                          ║     │
│   ║  依未成年保護規定,        ║     │  ← 內容文字 14pt;#FFFFFF
│   ║  每日遊戲時間上限為2小時。  ║     │
│   ║  今日配額已用盡。          ║     │
│   ║                          ║     │
│   ║  遊戲將於今日結束,        ║     │
│   ║  明日 00:00(UTC+8)       ║     │  ← 午夜重置說明
│   ║  自動重置。                ║     │
│   ║                          ║     │
│   ║  距離重置倒數:            ║     │
│   ║       06:32:15            ║     │  ← 倒數至午夜計時器(HH:MM:SS)
│   ║                          ║     │
│   ║  [      確認登出      ]   ║     │  ← 唯一按鈕;背景 #C0392B;高度 44pt
│   ║                          ║     │
│   ╚══════════════════════════╝     │
│                                    │
│  (遊戲已鎖定;不可返回遊戲;無繼續選項)│
└────────────────────────────────────┘

未成年版行為規格:


SCR-015:Settings(設定)

┌────────────────────────────────┐
│ ←  設定                         │
│                                │
│  音效設定                       │
│  音樂音量    ●────────── 70%    │
│  音效音量    ●────────── 80%    │
│  震動回饋    [開 ●        ]     │
│                                │
│  顯示設定                       │
│  減少動畫    [       ● 關]      │  ← F19:無障礙動畫減少開關
│  (開啟後計時緊急改為靜態純紅色,無閃爍)│
│                                │
│  隱私設定                       │
│  Cookie 同意管理                │
│  [必要 ✓] [分析 □] [行銷 □]    │  ← REQ-016 AC-3:可隨時撤回同意
│  [    更新 Cookie 設定    ]     │
│                                │
│  [    重播新手引導    ]          │  ← REQ-012 AC-4a:可重播教學
│                                │
│  隱私權政策                → [連結] │
│  幫助 / 常見問題           → [連結] │
│  ────────────────────────────  │
│  [      登出帳號(紅色按鈕)    ] │
│                                │
│ 娛樂性質,虛擬籌碼無真實財務價值  │
└────────────────────────────────┘

行為規格:

登出(在遊戲中觸發)Mid-Game Logout Special Case:

若玩家從 SCR-007(遊戲中)導航至 SCR-015 並點擊登出,確認對話框顯示強化警告:

i18n key: settings.logout_confirm_midgame = '您正在遊戲中!離開將視同棄牌,本局下注籌碼將損失。確定登出?'

確認後:Server 處理玩家棄牌 → Client 清除 JWT tokens → 導向 SCR-001(登入畫面)

從 SCR-007 開啟時的特殊限制:

音訊設定持久化:


SCR-016:籌碼商店(Chip Store,v1.x 佔位)

Entry: SCR-004 大廳「購買籌碼」按鈕;SCR-013 充值入口

Exit: 返回按鈕 → 返回上一頁

┌──────────────────────────────────────────────────┐
│  ← 返回                         籌碼商店          │
│                                                   │
│                                                   │
│          🔒 功能即將推出                           │
│                                                   │
│  ┌──────────────────────────────────────────────┐ │
│  │ 本遊戲使用虛擬籌碼,不可兌換現金              │ │
│  │ 或任何形式之有價資產。                        │ │
│  └──────────────────────────────────────────────┘ │
│                                                   │
│  籌碼購買功能將於後續版本推出,                    │
│  敬請期待。                                        │
│                                                   │
│  [              返回大廳              ]            │
│                                                   │
│  本遊戲為娛樂性質,虛擬籌碼無任何真實財務價值       │
└──────────────────────────────────────────────────┘

行為規格:


6. Animation Specifications(動畫規格)

6.0 畫面轉場動畫 (Screen Transition Animations)

轉場動畫類型時長Easing備注
SCR-001 → SCR-003Overlay(疊加於 SCR-001)首次啟動,Cookie Banner 以 Overlay 方式顯示,非獨立跳轉
SCR-001 → SCR-004Fade Out / Fade In0.3sLinear載入完成(非首次啟動,Cookie 已同意,直接進入大廳)
SCR-003 → SCR-004Fade Out / Fade In0.3sLinearCookie 同意後繼續載入至大廳
SCR-004 → SCR-002Slide Left0.25sease-out年齡驗證觸發(點擊正式對戰且 age_verified=false)
SCR-002 → SCR-004Slide Right0.25sease-inOTP 驗證成功後返回大廳
SCR-004 → SCR-005Slide Left0.25sease-out
SCR-005 → SCR-006Slide Left0.25sease-out
SCR-006 → SCR-007Fade Out / Fade In0.4sLinear
SCR-007 → SCR-004 (離開)Fade Out / Fade In0.3sLinear
SCR-004 → SCR-008Fade Out / Fade In0.3sLinear教學入口從大廳進入
SCR-008 → SCR-004Fade Out / Fade In0.3sLinear教學完成返回大廳
SCR-007 → SCR-010Overlay / Slide Left0.25sease-out遊戲中開啟排行榜
SCR-007 → SCR-015Slide Left0.25sease-out遊戲中開啟設定
返回(任意)Slide Right0.25sease-in
Overlay Push (SCR-009/011/012)Fade In + Slide Up0.2sease-out
Overlay DismissFade Out + Slide Down0.15sease-in
SCR-004 → SCR-010Slide Left0.25sease-out大廳排行榜入口
SCR-010 → SCR-004Slide Right0.25sease-in排行榜返回大廳
SCR-004 → SCR-013/014/015Slide Left0.25sease-out
SCR-004 → SCR-016Slide Left0.25sease-out購買籌碼入口
SCR-013 → SCR-016Slide Left0.25sease-out充值入口
SCR-016 → SCR-004Slide Right0.25sease-in返回大廳
SCR-016 → SCR-013Slide Right0.25sease-in返回個人頁

UIManager.navigateTo(scene, transition) 方法 — 統一管理所有轉場,避免個別場景自行實作動畫。


6.1 Phase 轉換動畫總覽

Phase 轉換動畫名稱時長觸發條件
waiting → dealing發牌動畫(Deal Animation)3 輪批次並行(Round 1: 所有玩家牌 1 同時飛出 0.5s → Round 2: 牌 2 0.5s → Round 3: 牌 3 0.5s),總計 1.5sServer 廣播 phase=dealing
dealing → banker-bet莊家手牌亮牌提示;本地玩家收到 myHand 推送後立即翻牌顯示 P0 手牌;CMP-005「查看手牌」按鈕對莊家顯示0.3s(P0 手牌翻牌)發牌動畫完成 + Server 推送 myHand
banker-bet(莊家可查看手牌)莊家點擊「查看手牌」→ 發送 see_cards → Server 確認後回傳莊家 myHand → 莊家手牌翻面顯示0.3s(翻牌動畫)莊家本地玩家點擊 CMP-005 See Cards 按鈕
banker-bet → player-bet操作按鈕滑入0.3sServer 廣播輪到本玩家
player-bet → showdown全員翻牌(Showdown)0.3s × N 張(同時)Server 廣播 phase=showdown
showdown → settled結算籌碼飛行0.5sServer 廣播 settlement

注意: 動畫播放期間不阻塞玩家操作計時器(REQ-013 AC-2);計時器在 Server 端持續倒數。


6.2 發牌動畫(Deal Animation)

規格:

  1. 牌從桌面中央(牌堆位置)飛出
  2. 按座位順序依次飛向各玩家牌區(順時鐘,P0 最後)
  3. 每張牌飛行時長:0.5s(Ease Out)
  4. 落定後輕微彈跳(scale 1.0 → 1.1 → 1.0,0.1s)

🔊 音效:sfx_card_deal.mp3(每張牌落下時,pitch 略有差異)


6.3 翻牌動畫(Showdown Flip)

規格:

  1. 牌面沿 Y 軸旋轉(0° → 90°):0.15s
  2. 換牌面素材(face-down → face-up)
  3. 牌面沿 Y 軸完成旋轉(90° → 0°):0.15s

翻牌順序規格:

🔊 音效:sfx_card_flip.mp3(每張牌翻面一次)


6.4 三公揭示動畫(Sam Gong Reveal)

規格:

  1. 3 張牌邊框從白色漸變為金色(#D4AF37):0.2s
  2. 金色光暈從牌面向外擴散(Particle 效果):0.3s
  3. 「三公!」文字從牌面中央升起並淡出:0.5s(monospace 20pt,#D4AF37

🔊 音效:sfx_sam_gong_fanfare.mp3(三公出現,最高優先級打斷其他音效)


6.5 結算籌碼飛行動畫(Settlement Chips)

規格:

🔊 音效:勝方 sfx_win_jingle.mp3 + sfx_chip_collect.mp3;敗方 sfx_lose.mp3;平手 sfx_tie.mp3;全棄牌 sfx_all_fold.mp3(詳見 §6.8)


6.6 莊家破產動畫(Banker Insolvency)

規格:

🔊 音效:sfx_insolvency.mp3(banker_insolvent=true 時觸發)


6.7 計時器緊急動畫(Timer Urgent)

規格:

Expired 閃爍規格(WCAG 2.3.1 合規):

無障礙設定: 若 Settings(SCR-015)中「減少動畫」開關開啟,畫面震動改為 Timer Bar 靜態紅色(無閃爍);遵循 WCAG 2.3.1(閃爍頻率限制)及 WCAG 2.3.3(前庭覺敏感設計指引)。

🔊 音效:sfx_timer_urgent.mp3(≤5s 每秒循環)


6.8 音效規格 (Audio Specification)

SFX 資產清單:

Asset NameTrigger EventDurationNotes
sfx_card_deal.mp3發牌動畫每張牌落下0.3spitch 略不同每張增加沉浸感
sfx_card_flip.mp3showdown 翻牌0.2s每張牌翻面一次
sfx_chip_collect.mp3settlement chips 動畫0.5s贏家才播放
sfx_win_jingle.mp3本玩家 win result1.5s全螢幕特效時播放
sfx_sam_gong_fanfare.mp3三公出現(任意玩家)2.0s最高優先級打斷其他音效
sfx_lose.mp3本玩家 lose result0.8s
sfx_button_click.mp3所有按鈕 tap0.05s輕觸回饋
sfx_timer_urgent.mp3計時器剩餘 ≤ 5s0.3s 循環每秒播放一次
sfx_tie.mp3本玩家結算為 ties 陣列成員0.6s中性鐘聲,表示平手退注
sfx_all_fold.mp3所有玩家棄牌,莊家不戰而勝0.8s若本玩家為莊家播放 sfx_win_jingle;非莊家播放此音效
sfx_insolvency.mp3settlement.banker_insolvent=true0.8s低沉警示音,表示莊家破產
sfx_crown_transition.mp3莊家輪換(banker_seat_index 改變)0.4sv1.0 placeholder: sfx_button_click;正式版替換(詳見 §6.9)
bgm_lobby.mp3SCR-004 大廳循環低音量背景音樂
bgm_game.mp3SCR-007 遊戲中循環緊張節奏背景音樂

Cocos Creator AudioSource 架構:

音效優先級:


6.9 莊家輪換皇冠動畫 (Banker Crown Transition Animation)

當 Room State banker_seat_index 改變(在 waiting phase 開始時):

  1. 舊莊家皇冠:Fade Out (0.2s linear) + 縮小至 0.5×(0.2s ease-in)
  2. 同時:「新莊家:{玩家名稱}」橫幅從桌面頂部中央淡入(0.3s ease-out),停留 1.5s 後淡出(0.3s)
  1. 新莊家皇冠:延遲 0.1s 後 Scale 0→1 + Fade In(0.3s ease-out),位置:玩家頭像正上方
  2. 皇冠資產:fx_crown_appear.anim(Cocos Creator Spine 動畫 或 SpriteFrame 序列)

🔊 音效:sfx_crown_transition.mp3(詳見 §6.8 SFX 資產表;v1.0 placeholder 為 sfx_button_click,beta 前替換)


6.10 動畫效能約束 (Animation Timing Constraints)

動畫類型時長上限基準裝置幀率目標
發牌動畫(總計)≤ 1.5s≥ 30fps
翻牌動畫(每張)≤ 0.3s≥ 30fps
結算動畫≤ 0.5s≥ 30fps
三段合計 P90(發牌 1.5s + Showdown 0.85s(= 0.3s 翻牌 + 5 seats × 0.05s 交錯延遲 + 0.3s pause = 0.85s,依據 §6.3 規格) + 結算 0.5s = 合計 2.85s)≤ 3.0s≥ 30fps
三公揭示≤ 1.0s≥ 30fps
莊家破產≤ 0.8s≥ 30fps

測試方式(REQ-013 AC-2):


7. Color Palette & Typography(色彩與排版)

7.1 色彩系統

用途色彩名稱Hex 值使用場景
主色 — 桌面底色Primary Green#1A6B35遊戲桌面 felt 背景;像素風草地綠
重點 — 金Gold#D4AF37莊家皇冠;三公高亮;籌碼邊框;排行榜首位;計時條(金色模式)
警示 — 紅Loss Red#C0392B輸牌;棄牌按鈕;破產動畫;計時條(緊急);未成年防沉迷標題
操作 — 藍Action Blue#2980B9跟注按鈕;主要互動色;聊天氣泡(自身);進度條
成功 — 綠Success Green#27AE60勝利動畫;正向淨籌碼;救濟籌碼通知
警告 — 橙Warning Orange#E67E22計時條(中段警示);廳別選擇按鈕;player-bet Phase Indicator
Showdown 指示色 — 紫 (Showdown Phase Indicator)Showdown Purple#8E44ADshowdown phase UI 邊框/背景指示色
文字 — 白Text White#FFFFFF深色背景上所有主要文字
牌面 — 白Card BG#FEFEFE撲克牌牌面背景(接近但非純白,柔化像素感)
背景 — 深夜藍BG Dark#0D2137Splash 背景;疊加層背景基底
輔助文字 — 灰Subtitle Gray#7F8C8D輔助說明文字;棄牌標籤;免責聲明
疊加遮罩Overlayrgba(0,0,0,0.85)防沉迷/結算疊加層背景

色盲安全原則(REQ-013 + Accessibility):

7.2 排版系統

層級字體字重字號顏色使用場景
H1 — 標題System Font(iOS: SF Pro;Android: Roboto)Bold(700)20pt#FFFFFF畫面主標題
H2 — 副標題System FontSemiBold(600)16pt#FFFFFF段落標題;按鈕文字
Body — 正文System FontRegular(400)14pt#FFFFFF說明文字;規則文字
Caption — 說明System FontRegular(400)12pt#7F8C8D輔助說明;免責聲明(最小 12pt)
Mono — 數字Monospace(iOS: SF Mono;Android: Roboto Mono)Bold(700)18pt(大)/ 14pt(中)/ 11pt(小)#D4AF37#FFFFFF所有籌碼數字;牌點數;計時數字

數字格式規則:


8. Localization(i18n 本地化)

8.1 語系配置

項目規格
主語系繁體中文(Traditional Chinese,zh-TW)
字串檔案路徑locale/zh-TW.json
字串引用規則所有 UI 顯示字串必須透過 i18n.t('key') 方法引用;禁止在 TypeScript 程式碼中硬編碼顯示文字
v1.0 限定僅繁體中文;多語系(英文/簡中)為 REQ-008 保留至 v1.x

8.2 i18n Key 命名規範

格式:{screen}_{component}_{purpose}
範例:
  game.action.call           → 「跟注」
  game.action.fold           → 「棄牌」
  game.phase.dealing         → 「發牌中」
  game.phase.banker_bet      → 「莊家下注中」
  game.phase.player_bet      → 「玩家決策中」
  game.phase.showdown        → 「翻牌比較」
  game.phase.settled         → 「結算完成」
  game.sam_gong_label        → 「三公!」
  game.banker_insolvent      → 「破產!」
  game.fold_label            → 「棄牌」
  game.tie_label             → 「平手退注」
  game.insolvency_zero       → 「⚠ -{bet}籌碼損失(因莊家破產,本金無法取回,實際損失 -{bet})」
  settlement.rake_label      → 「本局抽水:」
  settlement.next_round      → 「繼續下一局」
  settlement.leave_lobby     → 「返回大廳」
  tutorial.skip_rule         → 「跳過說明 ×」
  tutorial.complete_title    → 「教學完成!」
  tutorial.escrow_explain    → 「下注後,對應籌碼會暫時凍結,結算後返還或支付」
  tutorial.round3.tie_concept → 「當雙方點數相同時,系統會進行加時比牌(D8)。在極少數情況下仍會平局,此時雙方退注」
  tutorial.round3.result_tie → 「平手!您的100籌碼退回,本局結算為0。」
  anti_addiction.adult_warning → 「您已連續遊玩 {minutes} 分鐘,請適度休息,注意健康。」
  anti_addiction.underage_stop → 「今日遊戲時間已達上限(2 小時)。依未成年保護規定,請明日再來。」
  anti_addiction.continue    → 「我知道了,繼續遊戲」
  anti_addiction.logout      → 「確認登出」
  rescue_chips.awarded       → 「您的籌碼已不足,系統已補發 1,000 救濟籌碼」
  lobby.disclaimer           → 「娛樂性質,虛擬籌碼無真實財務價值」
  matchmaking.timeout        → 「配對超時,請稍後再試」
  matchmaking.expanding      → 「⚡ 擴大配對中({tiers})」
  errors.otp_daily_limit_exceeded → 「今日OTP請求已達上限,請於次日UTC+8 00:00後重試」
  lobby.chip_edge_500_999    → 「籌碼不足進入任何房間,請完成每日任務或等待每日免費籌碼(每日 00:00 UTC+8 重置)」
  lobby.daily_chip_claim     → 「領取今日籌碼 +5,000」

8.3 locale/zh-TW.json 結構(完整命名空間)

頂層命名空間清單:gamesettlementtutorialanti_addictionrescue_chipslobbymatchmakingsettingsaccessibilitychaterrorsleaderboardroom

{
  "game": {
    "action": {
      "call": "跟注",
      "fold": "棄牌",
      "see_cards": "查看手牌",
      "confirm_bet": "確認下注"
    },
    "phase": {
      "waiting": "等待玩家加入",
      "dealing": "發牌中",
      "banker_bet": "莊家下注中",
      "player_bet": "玩家決策中",
      "showdown": "翻牌比較",
      "settled": "結算完成",
      "waiting_new_banker": "等待玩家加入,新莊家為:{player_name}"
    },
    "sam_gong_label": "三公!",
    "banker_insolvent": "破產!",
    "fold_label": "棄牌",
    "tie_label": "平手退注",
    "insolvency_zero": "⚠ -{bet}籌碼損失(因莊家破產,本金無法取回,實際損失 -{bet})",
    "new_banker_banner": "新莊家:{name}",
    "timer_expired": "時間到"
  },
  "settlement": {
    "rake_label": "本局抽水:",
    "next_round": "繼續下一局",
    "leave_lobby": "返回大廳",
    "all_fold_banner": "全員棄牌,莊家無損益"
  },
  "tutorial": {
    "skip_rule": "跳過說明 ×",
    "complete_title": "教學完成!",
    "progress": "新手引導({current}/{total})",
    "chip_system_title": "籌碼系統說明",
    "escrow_explain": "下注後,對應籌碼會暫時凍結,結算後返還或支付",
    "step_completed": "完成!",
    "round1": {
      "intro": "歡迎來到三公教學!讓我們開始第一局。",
      "sam_gong_explain": "恭喜!您拿到三公(3張花牌)!這是最高手牌。",
      "win": "您贏了!三公打敗一切非三公手牌。"
    },
    "round2": {
      "points_explain": "普通牌型以點數決勝負(3張牌點數相加,取個位數)。您的5點打敗對方的3點。",
      "win": "您贏了!較高點數獲勝。"
    },
    "round3": {
      "tie_concept": "當雙方點數相同時,系統進行加時比牌(D8)。在極少數情況下仍會平局,此時雙方退注。",
      "result_tie": "平手!您的100籌碼退回,本局結算為0。"
    }
  },
  "anti_addiction": {
    "adult_warning": "您已連續遊玩 {minutes} 分鐘,請適度休息,注意健康。",
    "underage_stop": "今日遊戲時間已達上限(2 小時)。依未成年保護規定,請明日再來。",
    "underage_mid_game_banner": "今日遊玩即將達上限,本局結算後將自動登出",
    "continue": "我知道了,繼續遊戲",
    "logout": "確認登出"
  },
  "rescue_chips": {
    "awarded": "您的籌碼已不足,系統已補發 1,000 救濟籌碼"
  },
  "lobby": {
    "disclaimer": "娛樂性質,虛擬籌碼無真實財務價值",
    "daily_chip_claim": "領取今日籌碼 +5,000",
    "chip_edge_500_999": "籌碼不足進入任何房間,請完成每日任務或等待每日免費籌碼(每日 00:00 UTC+8 重置)",
    "daily_task_entry": "每日任務",
    "weekly_task_tab": "每週任務(即將推出)"
  },
  "matchmaking": {
    "timeout": "配對超時,請稍後再試",
    "expanding": "⚡ 擴大配對中({tiers})",
    "searching": "正在尋找同廳對手"
  },
  "settings": {
    "reduce_animation": "減少動畫",
    "reduce_animation_hint": "開啟後計時緊急改為靜態純紅色顯示,無閃爍(符合 WCAG 2.3.1)",
    "replay_tutorial": "重播新手引導",
    "cookie_management": "Cookie 同意管理",
    "music_volume": "背景音樂音量",
    "sfx_volume": "音效音量",
    "vibration_feedback": "振動回饋",
    "logout": "登出帳號",
    "logout_confirm": "確定要登出嗎?登出後需重新登入。",
    "logout_confirm_midgame": "您正在遊戲中!離開將視同棄牌,本局下注籌碼將損失。確定登出?",
    "tutorial_replay_disabled_midgame": "本局結束後方可重播教學",
    "privacy_policy": "隱私權政策",
    "help_faq": "幫助 / 常見問題"
  },
  "accessibility": {
    "call_button": "跟注,下注金額 {amount} 籌碼",
    "fold_button": "棄牌,放棄本局",
    "timer_bar": "剩餘時間:{seconds} 秒",
    "avatar_banker": "{name},莊家,籌碼 {balance}",
    "avatar_player": "{name},閒家,籌碼 {balance}"
  },
  "chat": {
    "report_success": "舉報已提交,謝謝您的回報",
    "input_placeholder": "輸入訊息(最多200字)",
    "report_reason": {
      "spam": "垃圾訊息",
      "harassment": "騷擾行為",
      "inappropriate": "不當內容",
      "cheating": "作弊嫌疑",
      "other": "其他"
    }
  },
  "errors": {
    "rate_limit": "操作過於頻繁,請稍後再試",
    "reconnecting": "連線中斷,正在重新連線... (嘗試 {attempt}/{max})",
    "reconnect_failed": "重連失敗",
    "otp_daily_limit_exceeded": "今日OTP請求已達上限,請於次日UTC+8 00:00後重試",
    "bet_exceeds_balance": "下注金額超過您的籌碼餘額",
    "room_full": "此房間已滿,請選擇其他房間",
    "room_not_found": "找不到此房間,請確認 ID 是否正確",
    "session_expired": "登入已過期,請重新登入",
    "server_error": "伺服器發生錯誤,請稍後再試",
    "kicked_from_room": "您已被移出房間",
    "account_banned": "您的帳號已被封禁,如有疑問請聯繫客服",
    "server_maintenance": "伺服器維護中,預計 {time} 恢復",
    "action_timeout": "操作逾時,請重試或檢查網路連線",
    "chat_content_filtered": "訊息含有不允許的內容,請修改後重新發送",
    "insufficient_chips_for_tier": "您的籌碼不足以進入此廳(需 {required} 籌碼,目前僅有 {current} 籌碼)",
    "already_in_room": "您已在其他房間中,請先結束目前的遊戲再加入新房間",
    "leave_mid_game_confirm": "離開後視同棄牌,本局已下注籌碼將損失。確定離開嗎?"
  },
  "leaderboard": {
    "my_rank_unranked": "-- / 未上榜",
    "last_updated": "更新時間:{time}",
    "weekly_tab": "週榜",
    "chip_tab": "籌碼榜",
    "rank_label": "#{rank}",
    "loading": "載入中..."
  },
  "room": {
    "id_copied": "已複製房間 ID",
    "create_success": "房間建立成功",
    "waiting_for_players": "等待玩家加入..."
  }
}

9. Accessibility(無障礙設計)

9.1 觸控目標

元件最小觸控目標
所有按鈕(Call、Fold、確認等)44×44pt(符合 Apple HIG / WCAG 2.1 SC 2.5.5)
計時條拇指(Bet Slider thumb)44×44pt(視覺 24pt,觸控擴展 ±10pt)
聊天氣泡(可點擊舉報)44×44pt
導航列圖示44×44pt
廳別選擇按鈕最小 64×56pt

9.2 色盲安全設計

設計場景色彩解法輔助機制
勝(+)/ 敗(-)區分綠色 / 紅色必須同時顯示 +N / -N 符號及「贏」/「輸」文字標籤
計時條緊急藍→橙→紅漸變同時顯示剩餘秒數數字
三公高亮金色邊框同時顯示「三公!」文字標籤
莊家識別金色邊框皇冠圖示(不純靠顏色)
Phase Indicator不同背景色同時顯示文字 Phase 名稱

9.3 Screen Reader 標籤規格

所有關鍵互動元素須設置 accessibilityLabel(iOS)/ contentDescription(Android):

元件accessibilityLabel 值(zh-TW)
Call 按鈕跟注,下注金額 {amount} 籌碼
Fold 按鈕棄牌,放棄本局
計時條剩餘時間:{seconds} 秒
玩家頭像(莊家){name},莊家,籌碼 {balance}
玩家頭像(閒家){name},閒家,籌碼 {balance}
牌(暗牌)暗牌
牌(亮牌){suit}{value},{points} 點
Cookie 同意按鈕接受所選 Cookie 類型
防沉迷確認按鈕確認已閱讀防沉迷提醒,繼續遊戲

9.4 對比度要求

對比度色彩表(含遊戲桌面免責聲明特例):

前景色背景色對比比率WCAG AA(4.5:1)處置
#FFFFFF(白字)#1A6B35(桌面綠)~5.1:1通過正文文字可直接使用
#7F8C8D(灰字,免責聲明)#1A6B35(桌面綠)~3.2:1不通過(低於 4.5:1)需加背景條
#7F8C8D(灰字,免責聲明)rgba(0,0,0,0.65) overlay blend~5.1:1通過(AA 合規)採用半透明黑色底條

免責聲明桌面場景緩解措施(SCR-007、SCR-009、SCR-010):


10. Platform Notes(平台技術規格)

10.1 Cocos Creator 3.8.x 場景結構

Scene Hierarchy(Cocos Creator 3.8.x Node Tree):

Canvas(設計解析度:750×1334)
└── SafeArea                          // Safe Area Adapter(處理 Notch/Home Bar)
    ├── UIManager                     // 全域 UI 管理器(Scene 切換、疊加層管理)
    │
    ├── Screens/                      // 所有畫面節點(同一時間只有一個 active)
    │   ├── SplashScreen              // SCR-001
    │   ├── AgeGateScreen             // SCR-002
    │   ├── CookieBannerScreen        // SCR-003(Web 限定)
    │   ├── LobbyScreen               // SCR-004
    │   ├── RoomTierScreen            // SCR-005
    │   ├── MatchmakingScreen         // SCR-006
    │   ├── GameTableScreen           // SCR-007(最核心)
    │   ├── TutorialScreen            // SCR-008
    │   ├── LeaderboardScreen         // SCR-010
    │   ├── ProfileScreen             // SCR-013
    │   ├── DailyTaskScreen           // SCR-014
    │   ├── SettingsScreen            // SCR-015
    │   └── ChipStoreScreen           // SCR-016 籌碼商店(v1.x 佔位)
    │
    └── Overlays/                     // 疊加層(始終在 Screens 上方)
        ├── SettlementOverlay         // SCR-009(opacity toggle)
        ├── ChatPanel                 // SCR-011(slide-in panel)
        ├── AntiAddictionOverlay      // SCR-012(最高層級,全螢幕)
        └── ToastManager              // 全域 Toast 通知(rescue chips 等)

設計解析度: 750×1334(iPhone 8 基準);Cocos Creator 設定 fitHeight 縮放策略

Canvas Scaler: Canvas 組件(Cocos Creator 3.8.x: import { Canvas } from 'cc',設定 FitMode = FIXED_HEIGHT);寬度超出部分裁切


10.2 TypeScript 元件命名規範

類型命名規則範例
Cocos Script 元件PascalCase + 功能後綴GameTableController.ts
UI 元件腳本CMP-ID + 名稱CardComponent.tsChipStackComponent.ts
畫面管理器Screen 名稱 + ManagerGameTableManager.ts
本地化i18n 前綴i18nManager.ts
Colyseus 相關Colyseus 前綴ColyseusRoomClient.ts

嚴格禁止(CI Gate 掃描):


10.3 Asset 命名規範(snake_case)

資源類型命名格式範例
撲克牌牌面card_{suit}_{value}.pngcard_spade_k.pngcard_heart_a.png
撲克牌背面card_back.pngcard_back.png
籌碼chip_{denomination}.pngchip_100.pngchip_1000000.png
UI 圖示ic_{name}.pngic_crown.pngic_disconnect.png
特效fx_{name}.png / fx_{name}.animfx_sam_gong_glow.pngfx_deal_card.anim

三公光暈資源說明: 三公光暈使用兩個版本:靜態 fx_sam_gong_glow.png(三公手牌持續疊加光暈,用於 CMP-001 三公高亮狀態疊加);動畫 fx_sam_gong_glow.anim(三公揭示動畫序列,用於 §6.4 Sam Gong Reveal 動畫)。兩個資源並存,職責不同。

背景bg_{name}.pngbg_table_felt.pngbg_lobby.png
頭像預設avatar_default_{n}.pngavatar_default_1.png
字型font_{name}.ttffont_pixel.ttffont_mono.ttf

10.4 Sprite Atlas(精靈圖集)

Atlas 名稱包含內容最大尺寸
cards atlas [CC Auto Atlas]所有 52 張牌牌面 + 背面;共 53 張2048×2048
chips atlas [CC Auto Atlas]9 種面額籌碼幣1024×512
ui_icons atlas [CC Auto Atlas]所有 UI 圖示(皇冠、斷線、設定、聊天等)1024×1024
fx atlas [CC Auto Atlas]特效素材(光暈、粒子基礎元素)1024×1024

Atlas 格式說明: 使用 Cocos Creator 3.8.x Auto Atlas 功能(將素材放入 atlas/ 資料夾,在 Creator 編輯器中設定 Auto Atlas 組件);不使用外部 TexturePacker .plist 格式。Atlas 命名保留語意說明(如 'cards atlas'、'chips atlas'),實際引用在 CC 3.8.x 中透過 SpriteAtlas asset 引用。

打包策略: 使用 Cocos Creator Bundle 功能;遊戲核心資源為 main Bundle;教學模式資源為 tutorial Bundle(懶加載)

10.5 Colyseus Client 整合規範

// 正確範例:Client 僅顯示 Server 廣播資料
room.state.settlement.winners.forEach((winner) => {
  this.displayNetChips(winner.player_id, winner.net_chips); // 只顯示,不計算
});

// 錯誤範例(禁止):Client 自行計算
// const netChips = bet * multiplier; // ❌ 禁止

10.6 效能預算 (Performance Budget)

動畫時長上限詳見 §6.10(Animation Timing Constraints);本節規範 GPU 記憶體、Draw Call 及 Bundle 大小指標。

項目規格
GPU 紋理記憶體上限≤ 128MB(基準裝置 2GB RAM 之 6.25%)
SCR-007(遊戲中)最大 Draw Call≤ 80
Bundle 大小目標 — main bundle≤ 5MB(壓縮後)
Bundle 大小目標 — tutorial 子包(懶加載)≤ 2MB
紋理壓縮格式 — AndroidETC2(RGBA8);ASTC 4×4 若裝置支援
紋理壓縮格式 — iOSASTC 4×4(fallback PVRTC)
目標幀率60fps;降功耗模式 30fps(可在 SCR-015 設定中切換)
記憶體清理 — 離開 SCR-007cc.resources.release() 釋放遊戲 Atlas
記憶體清理 — 回到大廳釋放遊戲音效資源

10.7 Colyseus Room State 欄位參考(Client 依賴欄位)

欄位名稱型別說明相關 Phase
phasestring enumwaiting/dealing/banker-bet/player-bet/showdown/settled全局
banker_seat_indexnumber莊家席位索引(0~5)全局
action_deadline_timestampnumber (ms)當前行動截止時間(Unix ms)banker-bet/player-bet
min_betnumber本廳最低下注額banker-bet/player-bet
max_betnumber本廳最高下注額banker-bet/player-bet
quick_bet_amountsnumber[]Server 建議快速下注金額banker-bet/player-bet
banker_bet_amountnumber莊家本局下注額(閒家 Call 按鈕顯示用)banker-bet/player-bet
current_potnumber當前底池金額(隨玩家下注即時更新,用於 SCR-007 底池顯示)banker-bet/player-bet/showdown
players[N].chip_balancenumber玩家N當前籌碼餘額全局
players[N].seat_indexnumber玩家N席位序號全局
players[N].isConnectedboolean玩家N連線狀態全局
players[N].player_idstring玩家N識別碼全局
players[N].display_namestring玩家N顯示名稱全局
revealed_cardsobject[]showdown 後各玩家已揭示的牌組showdown/settled
settlementobject結算完整結果(見 §5 SCR-009 schema)settled
settlement.winnersobject[]勝方清單settled
settlement.losersobject[]敗方清單settled
settlement.tiesobject[]平手清單settled
settlement.foldersobject[]棄牌清單settled
settlement.insolvent_winnersobject[]莊家破產-受影響勝方settled
settlement.rake_amountnumber抽水金額settled
settlement.banker_insolventboolean莊家是否破產settled
settlement.banker_remaining_chipsnumber結算後莊家剩餘籌碼settled
matchmaking_status.expanded_tiersstring[]擴大配對中的相鄰廳別名稱清單(空陣列 [] 表示未擴展,有值時如 ["白銀廳","青銅廳"] 表示已擴展至相鄰廳)waiting
player_state.room_activeboolean玩家是否在房間中(用於 Client 禁用重複加入)全局

此表為 PDD 客戶端實作參考,Colyseus Schema 型別定義詳見 EDD(STEP-07 產出)。


11. Design↔PRD Traceability(設計需求追溯矩陣)

REQ-ID需求描述(摘要)PDD 對應項目對應說明
REQ-001Server 端 Fisher-Yates 洗牌;Client 禁止洗牌邏輯§2.2 架構邊界、§10.2 禁止關鍵字Client bundle CI 掃描禁止關鍵字清單;TypeScript project references CI gate
REQ-002Server 發牌;Client 僅接收「手牌已發」通知;其他玩家暗牌CMP-001(face-down 狀態)、SCR-007 牌區佈局、§6.2 發牌動畫face-down 暗牌樣式;只有己方手牌顯示
REQ-003Server 比牌引擎;Client 不含比牌邏輯§2.2 架構邊界、SCR-009(結算顯示來自 settlement 廣播)三公標籤由 Server 廣播 is_sam_gong 驅動;Client 不計算點數
REQ-004Server 三步驟結算;Client 顯示廣播結果CMP-008(Settlement Card)、SCR-009(Settlement Overlay)、§6.5(籌碼飛行動畫)net_chips 顯示全來自 settlement 廣播;Client 不計算
REQ-005輪莊制(Rotating Banker System)CMP-003(莊家頭像 banker 狀態 + 皇冠圖示)、SCR-007(新莊家皇冠動畫 fx_crown_appear.anim;莊家輪換順序顯示於桌面右上角;Server banker_seat_index 廣播驅動)輪莊邏輯由 Server 執行;Client 僅顯示 banker_seat_index 對應座位皇冠與動畫;SCR-007 Phase Indicator 在 waiting phase 顯示「等待玩家加入,新莊家為:{player_name}」
REQ-006排行榜系統(Could Have)SCR-010(Leaderboard 畫面)、SCR-004(排行榜入口圖示)、SCR-007(遊戲中排行榜圖示)週榜/籌碼榜切換 Tab;Top 100 顯示;我的排名固定顯示
REQ-007聊天室系統(Could Have)SCR-011(Chat Panel)、CMP-009(Chat Bubble)、SCR-007(聊天圖示入口)200 字元上限;Rate Limit 靜默;斷線重連後不推歷史
REQ-010配對系統(Matchmaking)SCR-005(廳別選擇)、SCR-006(配對等待)、§3(Screen Inventory 流程)90s 倒數計時條;擴大配對提示;配對超時返回大廳
REQ-011Room State 同步;計時器由 action_deadline_timestamp 驅動CMP-006(Phase Indicator)、CMP-007(Timer Bar)、SCR-007 佈局CMP-007 說明 Client 用本地時鐘計算顯示;Server 判定超時
REQ-012新手引導(3 輪固定劇本,不消耗籌碼)SCR-008(Tutorial 畫面)教學模式標籤;3 輪動畫與正式局相同;完成後解鎖正式對戰
REQ-013UI / 動畫系統;像素風;動畫時長限制;免責聲明§2.1(P5 像素風原則)、§6(動畫規格)、§7(色彩排版)、免責聲明出現於 SCR-001/002/004/005/006/007/008/009/010/013/014/015/016 共 13 個畫面;另 SCR-014 task_reward_popup 子元件亦包含免責聲明:(1) SCR-001 啟動畫面;(2) SCR-002 年齡驗證;(3) SCR-004 主大廳;(4) SCR-005 廳別選擇;(5) SCR-006 配對等待;(6) SCR-007 遊戲桌面;(7) SCR-008 新手引導;(8) SCR-009 結算疊加層;(9) SCR-010 排行榜;(10) SCR-013 個人資料;(11) SCR-014 每日任務(含 task_reward_popup 子元件);(12) SCR-015 設定;(13) SCR-016 籌碼商店(v1.x 佔位,免責聲明需求已記錄)動畫時長預算 ≤ 3s;免責聲明 12pt 最小
REQ-014帳號系統;OTP 年齡驗證SCR-002(Age Gate OTP)、SCR-004(帳號登入流程)、SCR-013(個人資料)OTP 流程 ≤ 3 步驟;年齡驗證閘 100% 覆蓋
REQ-015防沉迷系統;成人 2h 彈窗;未成年 2h 強制登出CMP-010(Anti-Addiction Overlay)、SCR-012(防沉迷彈窗)、SCR-013(每日遊玩時間顯示)兩種版本(成人可繼續 / 未成年強制停止);必須明確點擊確認
REQ-016Cookie 同意橫幅(Web 限定)SCR-003(Cookie Consent Banner)3 類 Cookie 分別同意;歐盟 IP 非 pre-checked;台灣 IP 告知式
REQ-017反作弊;速率限制(Server 端,Client 顯示錯誤提示)SCR-007 → 操作按鈕 Processing 狀態;錯誤 Toast 通知(errors.rate_limit Toast)Client 顯示速率限制錯誤提示;不含反作弊邏輯
REQ-019個資刪除請求SCR-013(Profile/Account)→「刪除帳號」入口帳號設定頁提供刪除入口;刪除確認對話框
REQ-020a每日免費籌碼(主動領取)+ 救濟機制SCR-004(領取今日籌碼按鈕)、CMP-010(救濟籌碼 Toast)、SCR-014(每日任務)大廳顯示「領取今日籌碼」按鈕;救濟為底部 Toast
REQ-020b虛擬籌碼商店 IAP / 廣告(Should Have,條件啟用)SCR-013 或 SCR-004 → 籌碼商店入口(UI 佔位;實際功能依法律意見書 2026-05-15 決定)、SCR-016(籌碼商店佔位畫面)籌碼商店入口已預留;不含 IAP 計算邏輯
REQ-009每日/週任務籌碼(Daily/Weekly Chip Tasks)SCR-004(任務入口按鈕:底部快捷列「每日任務」圖示)、SCR-004(大廳底部快捷列:每日任務圖示 → SCR-014;排行榜圖示 → SCR-010)、SCR-014(每日任務與籌碼領取畫面:任務列表、完成進度、籌碼領取)任務列表及獎勵金額由 Server API 提供,Client 不硬編碼;每日籌碼任務在 SCR-004 大廳設有明顯入口按鈕(i18n key: lobby.daily_task_entry);週任務在 SCR-014 以獨立 Tab 顯示(v1.x 預留)
REQ-018KYC / 實名認證 / 防沉迷合規(Compliance)SCR-002(OTP 年齡驗證閘 / Age Gate)、CMP-010(Anti-Addiction Overlay:成人 2h 提醒 + 未成年 2h 硬停兩版本)、SCR-012(防沉迷彈窗:完整 wireframe 兩版本,含倒數至午夜計時器)KYC 年齡驗證由 Server 執行(currentYear - birthYear ≥ 18);Client 提供 SCR-002 OTP 輸入介面;防沉迷信號由 Server 廣播(anti_addiction_warning / anti_addiction_signal);Client CMP-010 依信號類型(adult/underage)顯示對應版本;所有合規 UI 元素不可在任何設定下被略過(P7 原則)
REQ-021每日任務系統SCR-014(Daily Tasks & Chips Claim)、SCR-004(每日任務圖示入口)任務列表;完成動畫;獎勵發放 Toast
REQ-008多語系 i18n 框架(v1.x)§8(Localization)、§2.1 P6(零硬編碼字串)v1.0 僅繁體中文;英文/簡中框架預留至 v1.x

12. Open Questions(待決設計問題)

以下問題需在實作前由 PM 或 Game Designer 決策:

#問題影響範圍截止日優先度負責人(Owner)
PDD-Q1美術風格最終選定(像素風 vs 賭場風);Beta A/B 測試後由 PM + Art Director 決定(BRD D7,截止 2026-07-21)所有畫面 SCR-001 ~ SCR-015 美術資源;需準備兩套 Atlas2026-07-21HIGHArt Director
PDD-Q2遊戲桌面 6 人空桌位(未滿員)的顯示方式:(a) 空白座位;(b) 匿名剪影;(c) 不顯示空座位SCR-007 Game Table 佈局2026-05-15(EDD 前)MEDIUMPM
PDD-Q3Settlement Overlay 的「下一局」自動倒數秒數(目前設計 5s);Game Designer 確認SCR-0092026-05-15MEDIUMGame Designer
PDD-Q4頭像圖片來源:(a) 固定預設 8 款像素頭像;(b) 玩家上傳自訂頭像;v1.0 決策CMP-003;SCR-0132026-05-15MEDIUMPM
PDD-Q5籌碼商店(REQ-020b)UI 設計是否現在預設佔位?法律意見書 2026-05-15 前不進入 SprintSCR-013 / 獨立 SCR-016(待分配)2026-05-15LOW(依 O1 法律意見)Legal/PM
PDD-Q6聊天室(REQ-007 Could Have)在 v1.0 是否實作?若實作,SCR-007 聊天圖示入口優先排入哪個 Sprint?SCR-011;SCR-007 頂部導航2026-05-15LOWEngineering Lead
PDD-Q7排行榜(REQ-006 Could Have)SCR-010 的我的排名「未上榜」時顯示什麼(顯示「--」或「未上榜,繼續加油!」)SCR-010RESOLVED — §8.3 leaderboard.my_rank_unranked = '-- / 未上榜',SCR-010 規格已明確LOWRESOLVED — N/A
PDD-Q8三公揭示動畫(§6.4)的 Particle 特效由 Cocos Creator 3.x Particle System 實作或 SpineAnimation;需 Art Director 確認§6.4 三公揭示動畫;fx_sam_gong_particles.png2026-05-15MEDIUMGame Designer
PDD-Q9私人房間(SCR-005 AC-4)建立後的「等待加入」畫面是否共用 SCR-006 還是獨立設計?SCR-005;SCR-006RESOLVED — SCR-006 已含私人房間等待模式B完整規格LOWRESOLVED — N/A
PDD-Q10每日任務(SCR-014)UI 中的任務完成動畫規格(checkbox 打勾動畫 / 彩帶爆炸動畫)需 Game Designer 確認。暫定預設規格:checkbox ✓ 打勾縮放動畫(scale 0→1.2→1.0,0.3s ease-out)+ #27AE60 綠色 + 0.1s 延遲後顯示完成文字(tutorial.step_completed);此規格為 PDD-Q10 解答前的過渡實作。如 2026-05-15 前未決定,使用暫定規格實作。SCR-0142026-05-15LOWGame Designer
PDD-Q11旁觀模式(Spectator Mode)— v1.0 Out-of-Scope 確認§3(旁觀模式說明)RESOLVEDv2.0 roadmapRESOLVED — N/A

PDD 文件結束。下一步:STEP-06 ARCH(架構設計文件)或 STEP-07 EDD(工程設計文件)。


文件維護聲明: 本 PDD 由 /devsop-autodev STEP-05 自動生成,依據 PRD v0.14-draft 及 BRD v0.12-draft。Client 設計嚴格遵循 Server-authoritative 原則;所有遊戲邏輯計算均由 Colyseus Server 執行,Client 僅為渲染顯示層。


變更追蹤

BUG-20260422-003:結算亮牌順序 + 發牌動畫 + 自己手牌逐張翻開

  1. 結算開牌順序應為「閒家先全部開完後,莊家最後亮牌決定輸贏」,增加刺激感。之前 startShowdownSequence 以 seat_index 升序亮牌,莊家不一定最後。
  2. 發牌階段應呈現「莊家依順時鐘逐張飛牌到每位閒家(含自己),共 3 輪」的 round-table 動畫,而非牌直接面朝下出現。
  3. 自己的手牌要一張張飛進來後翻面,而非 3 張同時顯示。
  1. startShowdownSequence 把莊家 seat 從排序中排出,再 append 至末;其他閒家照 seat_index 升序
  2. 新增 flyCard(fromEl, toEl, onLand) — 從來源位置飛出 🂠 卡背,420ms 帶旋轉與淡出
  3. 新增 startDealAnimation():莊家為原點,依順時鐘(banker+1 開始,莊家最後)3 輪發牌;每張間隔 140ms;每位玩家累計 3 張;飛到「自己」座位時增加 _myHandRevealedCount(逐張翻面 + coin drop 音效)
  4. handHTML(cards, reveal, dealtCount) — 支援限制顯示張數;未飛到的位置用 .card.ghost 佔位保留 layout 寬度
  5. render 邏輯在 _dealAnim.inProgress 時:自己只顯示 _myHandRevealedCount 張 face-up,其他玩家顯示 dealtForSeat[seat] 張 face-down
  6. myHand 訊息處理判斷是否為新一局(比對舊手牌不同)才觸發動畫;重連或 race condition 不會重播

BUG-20260422-001:押注/跟注 CMP-012 自動押注 checkbox 預設不勾選