opolyx đã có tiếng: hiệu ứng âm thanh và nút tắt tiếng
Trò chơi trước đây hoàn toàn im lặng. Giờ xúc xắc, quân cờ, tiền bạc, đồng hồ đấu giá và nhạc hiệu chiến thắng đều có tiếng — và một nút tắt được tất cả.

Nói đơn giản
Cho đến bản cập nhật này, opolyx không phát ra âm thanh nào. Không phải là một trò chơi yên tĩnh — mà im lặng theo đúng nghĩa đen: cả ứng dụng không có lấy một tệp âm thanh. Đổ được số sáu và bị phá sản nghe y hệt nhau.
Giờ đây những khoảnh khắc quan trọng đều nghe thấy được. Không có gì lặp vòng, không có gì phát nền — mỗi âm thanh gắn với một việc vừa xảy ra trên bàn cờ:
- xúc xắc, ngay khi bạn bấm Đổ — và một lần nữa khi chúng dừng lại ở con số của mình;
- quân cờ của bạn, mỗi ô một bước khi nó đi vòng quanh bàn cờ;
- tiền đổi chủ: tiền thuê, thuế, mua một ô đất, xây dựng;
- đồng hồ đấu giá đếm năm giây cuối cùng của lượt trả giá của bạn;
- vòng quay Jackpot, và nhạc hiệu khi bạn thắng hoặc thua một ván.
Âm thanh được bật sẵn. Nếu bạn muốn chơi trong im lặng, nút loa trên thanh trên cùng tắt mọi thứ chỉ bằng một cú nhấp, và lựa chọn đó được ghi nhớ trên thiết bị — đây là thiết lập đầu tiên opolyx từng lưu cho bạn.
Các đoạn clip chúng tôi đăng lên YouTube, Instagram và TikTok trước đây cũng im lặng. Giờ chúng mang đúng những âm thanh của trò chơi, nên một pha phá sản trong clip nghe giống hệt một pha phá sản trên bàn.
Cho người thích chi tiết kỹ thuật
Việc phát âm thanh dùng Web Audio thay vì một phần tử audio cho mỗi hiệu ứng. Các bộ đệm đã giải mã cho phép đa âm (tiếng xúc xắc rơi chồng lên tiếng bước quân cờ), lập lịch chính xác đến từng mẫu, và vẫn nằm trong chính sách bảo mật nội dung hiện có — mọi tệp đều được phục vụ từ tên miền của chính chúng tôi.
Sự kiện nào ứng với âm thanh nào được quyết định bằng một switch bao trùm toàn bộ hợp của các sự kiện trong engine, nên thêm một sự kiện mới sẽ làm hỏng bước kiểm tra kiểu cho tới khi có người quyết định nó có phát ra tiếng hay không:
// 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
}
}Bốn hiệu ứng chạy theo thời điểm chứ không theo sự kiện, vì thời điểm sự kiện từ máy chủ tới không phải lúc người chơi cảm nhận hành động. Tiếng đổ xúc xắc phát ngay khi nhấp (0 ms), tiếng rơi phát khi xúc xắc 3D dừng hẳn, tiếng bước phát theo từng ô trong hàng đợi nhảy của quân cờ, còn thắng/thua phát khi màn hình kết quả hiện ra.
| Hiệu ứng | Phát khi |
|---|---|
| dice-roll | lúc nhấp chuột, không phải lúc máy chủ trả lời |
| dice-land | khi hoạt ảnh xúc xắc 3D dừng hẳn |
| move-step | mỗi ô trong hàng đợi nhảy của quân cờ |
| tick | 5 giây cuối lượt hoặc lượt trả giá của chính bạn |
| victory / defeat | khi màn hình kết quả hiện ra |
Cả 26 tệp đều thuộc CC0, đã cắt gọn, chuẩn hóa đỉnh về −3 dBFS và mã hóa thành MP3 mono — MP3 chứ không phải Ogg, vì Safari trên iOS không giải mã được Ogg Vorbis. Kịch bản dựng sẽ kiểm tra đỉnh sau khi mã hóa: một phiên bản trước từng xuất ra các tệp đúng thời lượng, đúng dung lượng nhưng hoàn toàn không nghe thấy gì, do một bộ lọc fade đã làm câm mọi thứ sau khung thời gian của nó.
