Cấp độ của bạn cuối cùng cũng có ý nghĩa
Giờ mọi chỗ ngồi trên bàn đều kiếm được XP, lần lên cấp đầu tiên tốn 60 XP thay vì hai tuần chơi, và cấp độ trao cho bạn thứ hạng cùng thẻ sưu tầm.

Nói đơn giản
XP từng là một con số chẳng làm gì cả. Không có thứ gì trong trò chơi phụ thuộc vào cấp độ của bạn, và chỉ người thắng ván mới nhận được XP — nghĩa là khoảng hai phần ba số người ở mỗi bàn chơi trọn một ván, thua, thấy dòng "XP trận đấu +0", và chẳng có lý do gì để nghĩ con số ấy dành cho mình.
Bây giờ mọi chỗ ngồi đều có phần. Thứ hạng của bạn được trả công, những thế độc quyền bạn nắm khi ván kết thúc được trả công, và việc trụ tới cuối mà không bị loại cũng được trả công. Chiến thắng vẫn áp đảo — một chiến thắng đáng giá hơn gấp đôi kết quả thua tốt nhất có thể — nhưng thua đẹp thì không còn bằng không.
| Bạn đã làm gì | XP |
|---|---|
| Thắng ván đấu | +200 |
| Hạng nhì | +50 |
| Hạng ba | +30 |
| Hạng tư trở xuống | +15 |
| Mỗi thế độc quyền còn nắm lúc kết thúc (tối đa 3) | +10 |
| Trụ đến cuối mà không bị loại | +20 |
Đường cong được dựng lại quanh điều đó. Lần lên cấp đầu tiên nay tốn 60 XP, một ván tử tế là đủ — kể cả ván thua — trong khi trước đây phải mất chừng mười ngày chơi. Các cấp sau đắt dần lên chứ không đắt vọt một lần.
Và cấp độ giờ trao hai thứ. Cấp của bạn đi kèm một thứ hạng — tất cả 7 bậc, từ Sơ tuyển đến Bậc thầy — hiển thị cạnh tên bạn trên trang cá nhân và bảng xếp hạng. Còn khi vượt qua một cấp mốc, một thẻ bất động sản sưu tầm sẽ rơi vào bộ sưu tập của bạn: các cấp 3, 5, 7, 10, 13, 16, 20, và sau đó cứ mỗi 5 cấp một lần.

Cho người thích chi tiết kỹ thuật
Nửa thú vị của việc này là xoá đi các bản sao. Quy tắc cũ — mỗi 500 XP một cấp — được viết tay trong năm lần di trú cơ sở dữ liệu và ba tệp TypeScript, và chúng đã lệch nhau từ trước: dữ liệu kiểm thử gieo một cấp mà không phiên bản nào của quy tắc tạo ra được. Giờ chỉ còn một đường cong, trong một tệp, được phản chiếu y hệt trong cơ sở dữ liệu:
// packages/game-engine/src/progression.ts — one curve, mirrored exactly in SQL
step(L → L+1) = min(60 + 100·(L−1), 1500)
level 2 3 4 5 10 16 17+
xp 60 220 480 840 4,140 11,400 +1,500 eachPhép tính cố ý chỉ dùng số nguyên — không căn bậc hai, không dấu phẩy động — để SQL và TypeScript khớp nhau tại từng ranh giới một cách chính xác chứ không xấp xỉ, và một bài kiểm thử chạy trên cơ sở dữ liệu thật so sánh hai bên theo từng giá trị. Cả hai đường cong đều tăng, nên khi tính lại không ai vượt qua ai trên bảng xếp hạng.
Quá trình dựng nó lộ ra ba lỗi đã chạy khá lâu mà không bài kiểm thử nào bắt được: thanh cấp độ trên màn hình kết quả đọc phần thưởng của ván thay vì tổng XP, nên người chơi ở mọi cấp đều thấy cùng một thanh đóng băng ở mức 40%; thắng một ván ngắn lại bị ghi là thua, khiến những chiến thắng đó không bao giờ đẩy tiến độ nhiệm vụ thắng; và ở chế độ đồng đội, người đồng đội chiến thắng không được trả gì và bị ghi là thua, vì một trong hai người thắng không đứng nhất theo số thứ tự hàng. Cả ba đã được sửa, và mỗi lỗi đều có một bài kiểm thử thất bại nếu thiếu bản sửa.
