D-20260814-23|Ready 提交驗證與自動倒數¶
背景與驅動力¶
等待房原本只交換 ready: boolean,房主恆 Ready,且全員 Ready 後仍由房主另按開賽。真正的 loadout 交換、版本與資產驗證要到 preloading 才開始,因此玩家無法在仍可取消 Ready、換車或離房的階段驗證本場最終資料;起跑格 proof、matchId 與 loadout 也缺少一份可跨房主繼任與 RaceSession handoff 的共同鎖定包。
考慮過的選項¶
- Ready 只表示意願、由房主手動開始:無法證明倒數前所見資料就是開賽資料,否決。
- 個人 Ready 直接簽完整 roster:任何加入/移除都迫使所有人重簽,對仍未變動的個人選擇造成不必要清除,否決。
- 倒數斷線一律中止:安全但對三人房的一人斷線過度敏感,否決。
- 倒數斷線直接以 survivor 重抽起跑格或重算 matchId:破壞全員已驗證的 proof 與鎖定身分,否決。
- 個人聲明與集合共識分層、全員驗證後自動倒數、嚴格多數 survivor 沿用原鎖定包:採納。
決定¶
Ready 與集合驗證¶
- participant(含 host)只有 Ready/取消 Ready,沒有公開開賽按鈕。Ready 簽署房間、設定 digest、本人 membership epoch、完整
ClientVersionInfo與逐回合carRotation;Ready 中不得換車,取消後才可修改。 ReadyDeclaration不綁完整 roster。加入或移除 participant 只清除 ReadySet ack 與起跑格 ceremony;其他未變動玩家的個人聲明保留,新加入者以新 membership epoch 且初始未 Ready。場地、賽制或回合設定改變才清除全員聲明。- 全員 Ready 後形成 canonical
ReadySetContext。每端必須驗全部聲明簽章、相同 digest、A 軸版本、實際 admitted manifests、loadout 結構與 pinned checkpoint 的 B 軸資產版本,通過後才簽ReadySetAcknowledgement。 - 退役材質只由各端掃描相同的實際 manifests 形成不具名軟提示;材質 id、理由或布林宣告不進共識 wire,也不阻擋 ReadySet ack。
- 全 ack 後才執行 commitment/reveal 起跑格 ceremony;成功後形成並複製
LockedStartPackage,內含 ReadySet、聲明、ack、起跑 proof、matchId、startedAt、倒數 deadline 與簽章索引。倒數到期自動 handoff 至 preloading。
房間名單變動與權限¶
- host Ready 時不得移除 participant,必須先取消自己的 Ready。取消 host Ready 只撤銷 host 聲明;移除後其餘 participant 的個人 Ready 保留並重新形成集合驗證。
- waiting/collecting/verifying 可接受新 participant;他初始未 Ready,既有個人聲明保留。countdown 鎖住 participant admission,不允許補位。
倒數斷線與房主繼任¶
- room-control link 關閉只記為候選,必須再與 signaling presence 離開交叉確認才是倒數斷線;host 不得靠單方面關閉 link 排除在線玩家。
- 已確認倒數斷線者本場不重連、不補位;original roster、matchId、grid proof 與 slot mapping 不變,該玩家原格位留空並列入
preStartDisconnects。 - 倒數只在 survivor 至少 2 人且占 original roster 嚴格多數時繼續。否則取消本輪、移除已確認斷線者,剩餘 participant 全部回未 Ready。
- host 斷線時,只有 canonical 進房順序的決定性繼任者持有並能完整重驗同一
LockedStartPackage,且排除舊 host 後仍有嚴格多數,才可沿用原 deadline;不得重簽 Ready、重抽格位或接納新玩家。
RaceSession 邊界¶
- RaceSession 只從
LockedStartPackage讀取 car rotation,先排除preStartDisconnects再建立 transport;不得重讀可變車庫,也不得嘗試重連倒數斷線者。 - preloading 的 matchId-bound
LoadoutSubmission保留為 ledger 參與證明與第二道驗證,必須精確等於鎖定聲明。preloading 再次缺席者可進 disconnects,但實際開賽集合仍須滿足 original roster 的至少 2 人嚴格多數。 - 每回合物理拓撲只建立 survivor 車輛,起跑 slot 仍由 original
StartGridProof決定;空格不得壓縮或重排。
相容與遷移¶
目前 runtime_phase = pre_launch,沒有已發布 client、公開 wire 或正式持久資料需要相容。舊 set-ready 與公開 startMatch 直接移除,不提供 dual-read、alias 或 migration shim。
後果與影響¶
玩家在仍能自由取消的 waiting 階段就能看到驗證進度與軟提示,倒數輸入與正式比賽資料有共同可驗證錨;加入/移除也不會無端清除其他人的選車。代價是協議新增聲明、ack、起跑 ceremony 與鎖定包,且任一端可藉拒絕 ack 阻止本輪開始;這與其拒絕 Ready 的既有擾亂能力等價,並以取消 Ready/離房作為明確出口。