賽內機制¶
本檔角色:建立 / 配對房間、比賽中、比賽結束的所有流程。 賽中物理 / 破壞見 遊戲機制.md;經濟結算見 經濟系統.md;信譽變動見 信譽系統.md。
1. 房間建立 / 配對¶
1.1 模式¶
| 模式 | 說明 |
|---|---|
| Quick Match | 依 TrueSkill 動態窗口加入既有公開、允許快速加入且無參賽密碼的 waiting 房 |
| 私人房間 | 房主邀請;不套 Quick Match rating 搜尋窗口,正式結算與 TrueSkill 規則不變 |
1.2 TrueSkill 配對¶
詳見 算式表.md §20 與 程式架構/matchmaking.md。
- 多人版 TrueSkill(μ, σ 演化;TrueSkill 為 Microsoft 商標,本專案為自製整數定點實作、僅指示性沿用名稱——版權.md §11.1)
- 8 人 FFA 不平手(draw margin=0、無平手常數;算式表.md §20)
- 配對窗口:初始 ±5 rating(
displayRating = μ-3σ尺度),每 10 秒擴張 +5,上限 ±30 - 新人 σ 大(變動快);資深玩家 σ 小(穩定)
1.3 新手保護¶
新人 σ 大、配對窗口自然較寬(見 §1.2),不另設新手 rating 加成。信譽相關保護(註冊 < 7 天下限 400)詳見 信譽系統.md §4.1。
1.4 配對流程¶
1. 玩家點「配對」
2. 從 rooms topic 讀取已驗證的既有房公告
3. 在 ±window 內選擇 public、quick-match-enabled、無參賽密碼、版本相容且有空位的 waiting 房
4. 驗證 expected host 並建立等待房 star link;再送 participant join-request
5. 房主以最新狀態原子保留容量,必要時完成 OPAQUE participant admission
6. 每位 participant 選定逐回合 carRotation 並簽署 ReadyDeclaration
7. 全員 Ready 後形成 ReadySet;各端驗版本、manifest、結構與 B 軸資產,再簽 acknowledgement
8. 完成起跑格 commitment/reveal,複製不可變 LockedStartPackage,開始 READY_COUNTDOWN_SEC = 5 自動倒數
9. 倒數到期進 preloading;交換 matchId-bound LoadoutSubmission 並完成 package verification
10. 逐回合建立 world/rollback network、載入鎖定車輛與場地,通過 race-ready 屏障
11. 每回合開始 STARTUP_COUNTDOWN_SEC = 3;到期 GO!
presentation-ready 只可在場地、全車資產完成且 viewport 實際 render 至少一幀後回報;同賽道的下一回合也須建立新的 readiness 世代。任一 participant 在 GO 前離開,或 30 秒內沒有任何嚴格遞進的 milestone,整場在倒數與 frame pump 前取消:無棄賽/信譽/經濟結算,作廢舊 matchId、全員回原 RoomId 等待房。房主移除未完成的非 host participant、保留 host;剩餘成員重新 Ready、驗證並走 5 秒自動倒數,才會以新 startedAt 推導新 matchId。完整協議見 流程/比賽進行.md §1.7。
3/2/1/0 的 wire 與權威順序不因視覺改變;participant 與 spectator 依自己的本機網站主題 顯示 主題倒數 WebP。0 仍是正式起跑呈現訊號, frame pump 在倒數函式返回後立即開始,不等待圖片下載、解碼或播放。此處的「倒數」也不是 房間 admission、設定凍結或任何鎖定點。
1.5 房間設定(房主設定;Quick Match 沿用)¶
一場比賽(match)含 MATCH_ROUND_COUNT 個回合(round),一律由房主開房時設定;Quick Match 加入者沿用該既有房設定,不建立或覆寫預設房。圈數與賽程時間上限不是場地 GLB 屬性、逐回合由房間決定:
| 設定 | 範圍 | 預設 | 說明 |
|---|---|---|---|
回合數 MATCH_ROUND_COUNT |
1–5(暫定) | 3 | 一場比賽的回合數;積分制冠軍(算式表.md §20.1) |
| 每回合場地 | — | — | 房主逐回合各指定一軌(可重複用同一軌) |
圈數 lap_count(per 回合) |
1–10(RACE_LAP_COUNT_*) |
3 | 僅 lap_mode: loop 場地適用;linear / open 固定 1 |
| 賽程時間上限(per 回合) | 60–1800s(RACE_DURATION_*) |
600 | 達上限強制結束該回合依當前名次;防無限拖(Checkpoint 防抄近路機制依賴此上限) |
禁用晶片 disallowChip(per 回合) |
boolean | false | 保留車輛配置,但 HUD、輸入與 race runtime 停用所有晶片主動技能 |
| 人數上限 | 2–8 | — | 房主設、≤ 各回合場地 auto_player_max 的最小值(取最緊那軌,零件與共用介面.md §5.4) |
賽制設定頁必須從每個已解析 canonical GLB 的 root extras 讀取 auto_player_max,在人數超過
所有回合最小容量時直接顯示拒因並停用建房。任一回合的場地或容量尚未解析、格式非法時
fail closed;正式 matchmaking provider 在呼叫 room service 前以同一規則重驗,成功建房後再由
房間的 maxPlayers 對同時進房做原子 admission,避免只信任 UI 或競態超額。
場地只決定 lap_mode(幾何性質,見 場地.md §8.1)。選車:每位玩家賽前從車庫挑 MATCH_ROUND_COUNT 台(一台 / 回合、可重複用同台),見 流程/配對.md / 車輛組裝.md §1。晶片車可安排到 disallowChip 回合,選車時只警告;進入該回合後才停用主動技能。
1.6 開賽前版本檢核(preRaceVersionCheck)¶
兩軸版本檢核(版本規範.md):
- A 軸(client 版本):
checkCompatibility比對同房全員 client_version 等欄位,任一不符拒絕配對(版本規範.md §5、§7)。 - B 軸(資產 schema 版本):
- 開房當下 pin 一個帳本檢查點(= host 已同步的最新
LedgerCheckpointEvent,非任意 log head,版本規範.md §20);整房所有版本閘門對此快照算,後加入 peer 須 sync 到至少此檢查點,後來新增事件不中途踢人。 - ReadySet 驗證
carRotation全 N 台車的所有資產open4wd_version≥ 該 type 動態最低支援版;任一台含 unusable 資產 → 該 participant 不得完成 acknowledgement,整場不可進入自動倒數(不是 join admission,也不是單回合 DNF;須換件/遷移並湊齊 N 台全可用)。 - 算 per-type 降版本目標(最低非破壞相容類的最高版)。
- 發兩種提示:含棄用件 → 「該 type 全場降版本運算」(強提示);混非破壞較舊版 → 「數據可能有差異」(軟提示,老資產對新欄位用預設值)。
- 降版本場照常計排名 + 經濟;提示在開賽前顯示,開賽前退出無懲罰(§4),故自行退出是真實出口。
1.7 個人封鎖清單(blocklist,本地)¶
玩家可封鎖特定 PeerId——純本地清單、永不上鏈(上鏈反成公開羞辱名單與報復導火線),把無法客觀仲裁的人際問題轉為自力救濟、不消耗仲裁量能。與全域「黑名單(blacklist,帳本推導)」是兩件事,用語不得混用(信譽系統.md §6)。
| 情境 | 行為 |
|---|---|
| 瀏覽 / 自動配對 | 公開廣告維持隱私安全投影,不含 participant roster,因此不做進房前封鎖過濾 |
| 我當房主 | 拒絕封鎖對象加入(房主是成員資格權威);拒絕給通用原因、不揭露封鎖狀態(防報復) |
| 我進入別人房/封鎖對象後來加入 | 每次接受初始 room-state 與 participant roster delta 後取本機交集;隱藏對方文字/賽中圖示,顯示持續警示+一鍵離開。不自動退、不能要求踢人(房主權威不可侵),相同 roster 不重複提示 |
| 聊天 | 同一份清單、任何場合該 PeerId 訊息本地靜音(程式架構/chat-system.md §3) |
| 觀戰 | 不擋(觀戰者對賽者不可見、唯讀) |
實作見 程式架構/matchmaking.md。
1.8 玩家收藏清單與授權通關(本地)¶
收藏清單是玩家對 PeerId 的單向本機書籤,不是好友關係;上限 200、對方不知情、不上鏈、不跨裝置自動同步。公開狀態只從已驗簽的公開房間公告衍生,沒有資料時顯示「不在公開房間」,不得宣稱離線或推測私人房活動。
waiting 房主可從收藏清單建立預設空集合的授權通關快照。命中者可略過 participant 與 spectator 密碼證明,但封鎖、容量、狀態與版本檢查仍生效;名單不廣播、不進繼任,完整 reload 或 host loss 後清空。實作權威見 程式架構/player-favorites.md 與 程式架構/room-runtime.md。
2. 比賽中¶
2.1 P2P 同步¶
- Rollback Netcode:input 預測 + 錯誤回滾
- 固定 60Hz physics;dt 直接取
1 / FIXED_FRAMERATE_HZ秒精確值 ROLLBACK_FRAME_BUFFER_DEFAULT: 固定 8(不協商;7/10 只是不變式界標)- 純 rollback,不另加 input delay
- Snapshot 每 2 秒(120 frame)做 SHA-256 checksum 驗一致
- 〔LEDGER-R-079〕 checksum 等待容差 30 frame(0.5 秒):逾窗未到 = 該輪缺席、不阻塞多數決;mismatch 不觸發 rollback、僅累積 desync strike(連續 3 次升級)
2.2 物理共識¶
〔LEDGER-R-080〕 跨 peer 物理運算結果必須完全一致:
- f32 全物理 + 整數量化(INTEGER_SCALE)
- material lookup O(1) 純函數
- 浮點累積 deterministic 跨 wasm build 一致
- collider handle 對應 sub-mesh 固定索引
每 120 frame checksum 投票若有嚴格多數,只對持續落在少數的本端累積 desync strike;若沒有嚴格多數,整場 consensus-invalid,不以 state overwrite 掩蓋決定性問題。
2.3 回合 Consensus Anchor(唯一多簽證書)¶
- 正式 anchor 只在每回合終局建立;每 120 frame checksum 票不寫 ledger。
- original roster 依 PeerId 穩定排序選 proposer,逾時 deterministic fallback。候選只能落在 rollback finality 之外的有界 120-frame round-end tail。
presentPeers為原始 roster 扣除已確認離場者;至少floor(N/2)+1個不同 signer 背書,且每 peer 每回合最多簽一份。- 成功後把完整
RaceConsensusAnchorEventinline 放入MatchResultEvent.roundAnchors;證書以gridContextDigest + gridSeed綁定外層完整 grid proof。bounded window 未達 quorum 則該項為 null,整場只能非鑄幣結算,禁止單簽 fallback。 - 同回合兩張完整有效證書 → 保存 conflict signer evidence、整場
consensus-invalid,不選鏈、不套個人全域處罰。
與 rollback snapshot、帳本檢查點(全網狀態整併、治理多簽)皆為不同機制,見 資料系統.md §6。
2.4 HUD(最小化)¶
比賽頁 3D 為主體、HUD 疊加邊角拇指區;視覺布局見 美術資源/頁面線框.md §8。核心欄位:
| 元素 | 說明 |
|---|---|
| 名次 / 圈數 / 時間 | 左上;固定寬數字避免跳動 |
| 網路 | ping / desync / TURN,只在變差時突出 |
| 場地小地圖 | 右上 8 人位置點,可收合 |
| Endurance | 儲存 SOC remaining_energy_q / initial_energy_q × 100,另顯示可供輸出比例與「輸出受限」,黃色電池 widget |
| Thermal(核心 part+輪胎) | chip(必有)/motor/battery/全車最高溫 tire;以 (temperature−ambient)/(thermalLimitC−ambient) 的環境相對比例顯示漸變色 widget,不顯示精確溫度或輪位 |
| Fatigue worst-part | 常駐顯示當前 fatigue 最高 part(§2.4.2) |
| PartBroken | 自車新破壞零件的一次性文字+保留音效回饋;同幀可聚合數量,輪組以穩定 mount slot(FL/FR/RL/RR)標示。文字不只靠顏色、無位移動畫,既有音量/reduced-motion/色覺設定自然生效 |
| Skill 按鈕 | 依 chip slot 動態 1–4 個(含 weapon 技能);按下 → 加 chip heat → 執行 skill |
| 車身損傷 | 視覺 mask(裂痕 / 溫度色 tint,不顯示數字;見 零件與場景.md / 材質表.md) |
| 賽中圖示訊息 | 上方固定 sender HUD;每位 participant 最多一條,5 秒後消失,新訊息立即取代 |
Skill 按鈕無 cooldown timer、無 disabled 預警狀態:玩家自行判斷溫度餘額;觸發若使 chip 跨過 thermal_limit,該次技能仍完整執行,統一熱解算後 chip broken(之後所有 skill 按鈕灰掉 + 顯示 BURNED)。無「即將過熱」彈窗(設計選擇,見 遊戲機制.md §10)。
螢幕方向:建議橫向、不強制——直向進賽顯示一次性「建議橫向 🔄」toast(可記住不再提示)、不阻擋遊玩。直向適應 = 同錨點緊湊化:小地圖預設收合(本就可收合)、左上資訊列縮排、Skill 按鈕維持底部拇指區、圖示訊息 HUD 維持上方;橫向為設計基準(ui-frontend.md §10)。
2.4.1 操控與預設鍵位¶
玩家賽中唯一輸入 = 技能觸發(InputEvent = skill-trigger,程式架構/interfaces.md §3.1)——迷你四驅車無轉向(滾輪貼牆自走);橫向位移 = swerve_left/swerve_right 技能。預設鍵位(鍵盤 / 手把可由設定頁「自訂按鍵」重綁、程式架構/settings.md;觸控佈局固定):
| 輸入 | PC 鍵盤 | 手把(Gamepad API) | 觸控 |
|---|---|---|---|
| Skill slot 1–4 | 1–4(Hold 型按住) |
A/B/X/Y(✕○□△) |
底部中央鈕 1–4(§2.4) |
| 圖示訊息九宮格 | Enter(展開/關閉) |
— | 單一圖示鈕;點一格即送出並收合 |
| 比賽選單(含離開確認) | Esc |
Start |
頂部角落鈕 |
| 小地圖收合 | M |
Back/Select |
點小地圖本體 |
| 觀戰視角循環(外部觀戰/淘汰後) | C 切換自由/巡禮(自由視角 = WASD+滑鼠) |
RB 下一目標/LB 上一目標 |
螢幕右/左緣點擊切換目標 |
| 跟車距離(跟車模式) | 滑鼠滾輪/HUD −・數值・+ |
右搖桿 Y/HUD | 雙指縮放/HUD |
九宮格沒有文字輸入與隱藏訊息歷史;可輸入元件 focus 時仍依 編輯器操作.md §0.6 停用其他遊戲按鍵。不做陀螺儀/傾斜輸入。
觀戰相機快捷鍵只在外部 spectator 或本回合已淘汰 participant 生效;仍在比賽的 participant 不攔截 C、LB、RB 或畫面邊緣操作。鍵盤在可輸入元件 focus 時不觸發,手把按鍵採放開後再按的 rising-edge 語意,長按不連續跳換。目標切換沿固定 roster 循環,保留淘汰/完賽車並跳過離線者;完整模式語意見 流程/觀戰.md §3。
跟車距離為純本機 presentation 輸入,不屬於上述決定性 InputEvent。範圍 0.30–2.00 m、預設 0.50 m、HUD/滾輪步距 0.05 m;中央數值按鈕重設預設值。偏好保存於裝置本機,儲存失敗仍沿用本次 session 值;pagehide/freeze/轉為 hidden 時取消 debounce 並啟動 best-effort 寫入。手把 elapsed 每次最多採 250ms,visibility 切換重設取樣時鐘,避免回前景第一幀把距離跳到上下限。鏡頭維持世界 +Y,車體翻滾/倒置期間保留最後穩定水平朝向;完整規則見 D-20260810-01。
2.4.2 Fatigue Indicator 輪播防閃爍¶
Fatigue widget 常駐顯示「當前 fatigue 最高的 part」,避免在多個 part fatigue 接近時頻繁切換造成視覺干擾:
| 機制 | 規則 |
|---|---|
| dwell time | 切換新 part 後最少顯示 1.5 秒,期間即使 ranking 變化也不切換 |
| 動畫鎖定 | 切換過程播放短淡出 / 淡入 150ms,期間不接受新切換 |
| broken 強制切換 | part broken 觸發 200ms 紅閃後,立即切到下一個 worst(不受 dwell 限制) |
| 色盲區分 | fatigue 用盾形圖示、thermal 用溫度計圖示,避免單靠紅色判斷 |
worst part 選取:argmax(part.fatigue),tiebreaker tire > roller > weapon > body > motor > battery > chip > chassis(起跑全 0 → 顯示輪胎);多顆同類(4 tire / 6 roller)取該類最高一顆、不分位置、用類別圖示。色階:fatigue 綠(0–0.3)→ 黃(0.3–0.6)→ 橘(0.6–0.85)→ 紅(0.85–1.0);thermal 藍 → 白 → 黃 → 紅,兩者 hue 區隔避免混淆。
2.5 溝通系統¶
等待房文字詳見 程式架構/chat-system.md,賽中圖示詳見 程式架構/race-messages.md。
| 功能 | 規範 |
|---|---|
| 等待房文字聊天 | participant/spectator 共用;host-star 中繼原始簽章 envelope,host 驗 admission、來源、簽章與 roomId |
| 等待房防刷頻 | 送端/host per-sender 5 則/秒;host room-wide 20 則/秒+32,000 UTF-8 bytes/秒 |
| 文字過濾 | 完整原文傳送與留存,只在各裝置顯示時套玩家本機 literal 詞表;可開關 |
| 封鎖靜音 | 個人封鎖清單(§1.7)對象訊息本地靜音 |
| 近期隊友 | 比賽結束後在本機追蹤近 N 個玩家,供查公開頁與操作個人封鎖;不建立好友關係 |
| 收藏清單 | 可從排名加入單向本機收藏;不通知對方、不形成好友關係 |
| 賽中圖示訊息 | participant 以單一按鈕展開 3×3 九宮格;選取後送出並自動收合。九格在進入等待房完成 admission 時凍結,不在 3、2、1、GO 重新判定;spectator 唯讀接收。平均每 2 秒一則、burst 2。固定 HUD 每 sender 至多一條、5 秒,新訊息立即取代同 sender 舊訊息。賽內完全沒有自由文字 composer。完整契約見 程式架構/race-messages.md。 |
2.6 觀戰¶
| 規則 | 細節 |
|---|---|
| 進入觀戰 | 從正在進行的房間 join 觀戰 |
| 不簽章 | 觀戰者不參與 multisig(不影響共識) |
| 唯讀 replay | 外部觀戰主模式以同型物理重播已簽 input,但不具權威、不參與 checksum 多數決;版本/能力不足才用精簡 fallback |
| 視角控制 | 跟車 / 自由 / 巡禮;participant 另有「自己」快捷鍵;跟車距離與世界水平穩定規則同 §2.4.1 |
| 淘汰自動轉觀戰 | chassis broken(physicsRetired)→ 該回合直接切觀戰繼續看;battery/motor 失能不淘汰 |
3. 回合結束 / 比賽結束¶
一場比賽含 MATCH_ROUND_COUNT 個回合,循序進行:每回合各自結束 → 算回合名次 + 積分 → (非最後)載入下一回合 → 最後一回合後算總名次、結算一次。
3.1 回合結束條件(每回合)¶
| 條件 | 處理 |
|---|---|
〔LEDGER-R-081〕 完成該回合 lap_count 圈 |
玩家進入該回合「已完賽」狀態;其他玩家繼續 |
chassis broken(physicsRetired) |
該回合自動切觀戰;battery/motor 失能仍留場並可合法完賽(繼續下一回合、不整場出局) |
| 場上無未完賽存活車 | battery/motor 失能車進入單一回合級終局窗:最多 120 幀;全部線速度 < 0.05 m/s 且角速度 < 0.1 rad/s 連續 15 幀可提前結束。仍有存活車時不啟動此窗,回合時限始終優先 |
| 主動退出該回合 | 計該回合 DNF |
| 達該回合賽程時間上限(預設 600s、範圍 60–1800) | 強制結束該回合、依當前名次定該回合名次 |
〔LEDGER-R-082〕 回合結束 → 先分①已完賽、②未完賽存活、③未完賽失能(battery/motor functionalDisabled 或 chassis physicsRetired)、④未完賽退出;已完賽依完賽幀,其餘各區依圈數 → checkpoint 約束的量化 route 進度 → PeerId 排序,再給積分 P − k + 1(算式表.md §20.1)。合法完賽一旦成立,不因之後失能、退役或退出降級。
3.1.1 回合間(非最後一回合)¶
| 步驟 | 內容 |
|---|---|
| 累加積分 | 該回合名次 → P − k + 1 累加各玩家總積分 |
| 載入下一回合 | 下一回合場地 + 各自下一台車(carRotation[i+1]) |
| 〔LEDGER-R-083〕 新車初始狀態 | 載入下一回合的車即全新(fatigue 0 / temperature ambient / battery 滿 / 彈藥滿 / broken false,算式表.md §11);回合獨立、不共享狀態(非 reset 流程) |
| 回合內淘汰者 | chassis broken(physicsRetired)者仍繼續下一回合(換新車),不整場出局 |
3.2 比賽結束與結算(N 回合後)¶
最後一回合結束 → 比賽結束、per-match 結算一次:
- 〔LEDGER-R-084〕 總名次:N 回合積分加總由高到低;tiebreak 總完成時間(DNF 回合計該回合時限)→ PeerId lexicographic(算式表.md §20.1 / 流程/比賽結算.md)
- 組裝只含 match facts 的 candidate:
rounds[]、總名次、loadout proofs、完整 grid proof 與 inlineroundAnchors[];不含 payout/frontier - 完賽者核對上述事實與本機賽事記錄,達 original roster 嚴格多數後多簽
MatchResultEvent - multisig 通過 → 寫入 ledger;canonical fold 依事件位置前態計算獎金(算式表.md §13)與 royalty/三層分潤(算式表.md §14–§15)
- fold 原子套用經濟結果(一場比賽一筆事件、無獨立鑄幣 / 分潤事件,見 程式架構/ledger-settlement.md §5)
- DerivedState 自動套用:TrueSkill rating(μ/σ,依總名次、per-match 一次)+ 信譽變動(完賽 / 連勝 / 異常斷線,自
ranking/disconnectsderive、無獨立信譽事件;加分僅計 finisherCount ≥ 3 場 +24h 日額,見 信譽系統.md §2.2 / §10)
3.3 結算共識¶
- 〔LEDGER-R-085〕 所有完賽者只核對 match facts(rounds、ranking、loadouts、grid proof、inline anchors、disconnects)與 candidate hash;不得先算或簽 payout
- facts 一致且簽章達 original roster 嚴格多數 →
MatchResultEvent定稿;各 peer 日後在 canonical fold 依同一事件位置前態唯一計算 settlement - 否則(湊不滿 ⌊N/2⌋+1)→ 本場無結算、無事件(流程/比賽結算.md §9;無仲裁路徑——match facts 可由參賽端核對)
3.4 整除截斷(共識關鍵)¶
〔ECON-R-003〕 computeMatchPrize 用 bigint 整除,截斷的小數抹零消失:
50 × 8 × 14 × 67 = 375,200
375,200 / 10,000 (bigint) = 37 ← 真實值 37.52,小數截斷
5 個第 4–8 名拿 37 minor units,「失蹤」5 × 0.52 ≈ 2.6 不入任何人口袋。
為何抹零而非補給冠軍:所有 peer 在 canonical fold 對「應發總額」必須完全一致;補回邏輯任一細節歧異會使 DerivedState 分叉。抹零是純粹 bigint / 行為,跨 JS 引擎 / 硬體 / CPU 架構結果一致。
詳見 算式表.md §13。
3.5 排行榜(無,由 rating + 信譽自然顯示)¶
- 不設定全球排行榜
- TrueSkill rating 與 reputation 在玩家資訊頁顯示
- UGC rating(用 UGC 被使用次數 + 評分)可在 UGC 詳情頁查看
4. 棄賽 / 異常斷線¶
| 情境 | 處理 |
|---|---|
| waiting 房內離開(尚未接受 match-start) | 無懲罰(不計棄賽、不扣信譽);版本或封鎖衝突提示後自行退出即走此路。賽內 3、2、1、GO 不負責鎖定個人設定或重新裁決此狀態 |
| 〔LEDGER-R-086〕 賽中網路斷線 | race-mesh 獨立 generation 先走 15s 重連窗;GO 後逾時僅原 active roster 嚴格多數側可形成 network removal 並續賽,少數/平手側 partition-void、不結算。合法 removal 才 forfeit 整場、剩餘回合 DNF;room-control/spectator-stream 斷線不得改 race 資格。見 比賽進行.md §12 |
| 正式賽切至背景 | 回前景時若本機 simulation clock 落後超過 24 幀,三人以上在 900 幀內走 quorum state catch-up、超過 900 幀自我驅逐;2 人場因無獨立遠端多數,超過 24 幀即自我驅逐。不得在幽靈時間軸繼續並參與結算;local-test 維持暫停語意。見 network-sync.md §7.2 |
| 玩家 GO 後主動 quit | 先送 wire leave(reason: voluntary),再 best-effort 上鏈本人單簽 RaceLeaveEvent;立即只套用本人 disconnectCounts +1 與信譽 −5,不縮小 MatchResult quorum。若後續 MatchResult 合法定稿,才將本人列為整場 forfeit(剩餘回合 DNF、不算完賽、不領獎金) |
| 〔MOD-R-009〕 主動離場/異常斷線(每次) | 主動離場由本人 RaceLeaveEvent、異常斷線由合法 MatchResultEvent.disconnects 推導信譽 −5 與斷線計次 +1;兩者以 (matchId, peerId) 持久去重。MatchResult 只罰有本場簽章 loadout 者,absent 不罰;無 quorum 不得由少數替第三人扣分 |
| 回合 timeout(達該回合賽程時間上限,預設 600s / 範圍 60–1800) | 依當前名次定該回合名次(同 §3.1) |
5. 反作弊(賽內層)¶
詳見 程式架構/network-sync.md + 程式架構/security.md §1·§2。
| 攻擊 | 防禦 |
|---|---|
| 修改 client 物理 | snapshot checksum 多簽偵測 |
| 〔LEDGER-R-087〕 Input 偽造/畸形 | Race Sign Key 簽章/回合隔離;每幀最多 4 個不重複 skill,Event/Hold 型態與本回合 loadout chip schema 皆須相符 |
| 〔LEDGER-R-088〕 同幀 equivocation | (peer, frame) 首個 signed 值鎖定;本端觀測到第二個相異值立即 fail-closed;跨 DataChannel 選擇性首值的殘餘風險由 checksum 中止分歧(見 network-sync 殘餘風險) |
| Rapier collider 排序差異 | mesh fingerprint 跨 peer 比對 |
| 卡關 stall / grief(卡空 / 卡牆) | 卡空(掉出 / 脫離)→ 自動重定位(遊戲機制.md §12);卡牆(場內物理卡死)不另設偵測 = 當作無法完賽(形態太多難窮舉、避免誤判正常慢速;賽程時間上限 §1.5 兜底防無限拖、stall 無利益) |
| 〔LEDGER-R-089〕 抄近路 / 跳關 | Checkpoint 須依序點亮才算完賽 / 計圈;所有 peer deterministic 重算驗證 |
6. 比賽外影響¶
| 賽內事件 | 賽外影響 |
|---|---|
| 完賽 | 鑄幣 + UGC rating 累積 |
| 用到的 UGC | 三層分潤給創作者 + parent / grandparent fork |
| 排名 | TrueSkill μ, σ 演化 |
| 異常斷線(有本場 loadout 者) | 信譽 -5(absent 不罰;不觸發黑名單——黑名單為純仲裁三振) |
| 完賽者群組哈希 | 「24h K 場限制」防 self-reward(經濟系統.md) |
7. 對應外部模組¶
跨模組名稱、責任與實作路徑只由 程式架構.md §1 的模組表定義;本檔只描述 賽內行為。HUD 規格見 §2.4,視覺布局見 美術資源/頁面線框.md §8。