opolyx 終於有聲音了:音效與靜音按鈕
這款遊戲此前完全沒有聲音。現在骰子、棋子、金錢、拍賣倒數計時和勝利提示音都有了聲音——並且一個按鈕就能全部關閉。

通俗版
在這次更新之前,opolyx 完全不發出任何聲音。它不是"安靜",而是字面意義上的無聲:整個 App 裡沒有任何音訊。擲出六點和宣告破產聽起來一模一樣。
現在,重要的時刻都能聽見了。沒有迴圈播放,也沒有背景音——每一個聲音都對應棋盤上剛剛發生的事:
- 按下"擲骰"的瞬間的骰子聲,以及骰子停在點數上時的落定聲;
- 你的棋子在棋盤上移動時,每經過一格的腳步聲;
- 金錢易手的聲音:租金、稅款、購買地產、建造;
- 你出價的最後五秒裡,拍賣倒數計時的滴答聲;
- 大獎轉盤的聲音,以及一局結束時的勝利或失敗提示音。
聲音預設開啟。如果你更喜歡安靜地玩,頂欄的喇叭按鈕一鍵即可全部關閉,並且這個選擇會記在該裝置上——這也是 opolyx 第一次為你儲存偏好設定。
我們釋出到 YouTube、Instagram 和 TikTok 的精彩片段此前同樣是無聲的。現在它們採用與遊戲相同的音效,所以片段裡的破產聽起來就和牌桌上的破產一樣。
技術細節
播放使用 Web Audio,而不是為每個音效建立一個音訊元素。解碼後的緩衝區支援複音(骰子落定聲與移動腳步聲疊加)、樣本級精確排程,並且符合現有的內容安全策略——所有檔案都由我們自己的域名提供。
哪個事件對應哪個音效,由一個針對引擎事件聯合型別的窮盡 switch 決定,因此新增一種領域事件會導致型別檢查失敗,直到有人決定它是否需要發聲:
// lib/sound/events.ts — exhaustive over DomainEvent['kind']
export function soundForEvent(e: DomainEvent, viewerSlot: number | null): SoundId | null {
switch (e.kind) {
case 'rent_paid':
return e.payload.amount >= BIG_RENT ? 'cash-big' : 'cash';
case 'player_bankrupt':
return 'bankrupt';
// …every kind handled; no default, so a new event is a type error
}
}有四個音效由時機驅動而非事件驅動,因為伺服器事件到達的時刻並不是玩家感知到動作的時刻。擲骰聲在點選時(0 毫秒)響起,落定聲在 3D 骰子停穩時響起,腳步聲隨棋子跳格佇列逐格響起,勝負提示音則在結算畫面掛載時響起。
| 音效 | 觸發時機 |
|---|---|
| dice-roll | 點選時,而非伺服器響應時 |
| dice-land | 3D 骰子停穩動畫結束時 |
| move-step | 棋子跳格佇列中的每一格 |
| tick | 你自己回合或出價的最後 5 秒 |
| victory / defeat | 結算畫面掛載時 |
全部 26 個檔案均為 CC0 授權,經過裁剪、峰值歸一化到 −3 dBFS,並編碼為單聲道 MP3——選擇 MP3 而非 Ogg,是因為 iOS Safari 無法解碼 Ogg Vorbis。構建指令碼會在編碼後校驗峰值:早先的版本曾輸出時長正確、體積正確卻完全聽不見聲音的檔案,原因是一個淡出濾鏡把其時間窗之後的一切都變成了靜音。
