NON-PRODUCTION
Sugar Rush — tài liệu ghép client
Slot cluster / tumble 7×7. Sticky multiplier trong free spins. Có buy FS và buy Super FS.
Trang này chỉ được serve khi ENVIRONMENT != production.
1. Tổng quan
| Mục | Giá trị |
|---|---|
| Grid | 7 cột × 7 hàng · reels[col][row], row 0 = trên cùng |
| Pay | Cluster ≥5 (4-neighbor: trên/dưới/trái/phải) hoặc pay-anywhere ≥12 nếu PayAnywhereMode |
| Tumble | Ô thắng biến mất, symbol còn lại rơi xuống, ô trống fill từ trên |
| Sticky | Trong FS: mỗi lần cluster thắng trên ô, count tăng. Display = 2^(count-1) |
| FS | ≥3 scatter: 3→10, 4→12, 5→15, 6→20, ≥7→30 lượt |
| Buy FS | Giá = buy_free_spins_price × bet |
| Buy Super | Giá = buy_super_free_spins_price × bet. Seed sticky ×2 trên mọi ô |
| free_spin_type | 0 normal · 1 free · 2 super |
| Base path | /api/v1 |
Session gameplay nằm in-memory. Client bắt buộc gọi
GET /api/v1/gameplay trước khi spin.
Reconnect thì đọc lại state từ /gameplay (kể cả sticky multipliers).
2. Luồng ghép
- Mở game →
GET /api/v1/gameplay. Render board, bet, paytable, money, sticky nếu đang FS. - User chọn bet chỉ khi
is_free_spin = false. - Spin thường →
POST /api/v1/spinsbody{"bet": ...}. - Play tuần tự từng phần tử
win_result[](tumble). Highlight cluster theopositions. - Nếu
is_bonus_free_spin→ popup +N FS, chuyển UI free-spin. Hiện sticky theomultipliers. - Khi
is_free_spin: không trừ bet, tiếp tụcPOST /spinstớiis_finish_free_spin. - Buy →
POST /buy-freespinshoặcPOST /buy-super-freespins(cấm khi đang FS). - Luôn lấy số dư từ
user_moneycủa response vừa nhận.
3. Auth & envelope
Header
Authorization: Bearer <access_token> Content-Type: application/json
Mọi API dưới /api/v1 đều cần JWT. Trang docs không cần token.
Envelope
HTTP 200 + code = 0 là thành công. Payload nằm trong msg.
{
"code": 0,
"msg": { ... }
}
| code | Ý nghĩa |
|---|---|
0 | OK |
-1 | Unknown / thiếu JWT / token invalid (tùy HTTP status) |
-2 | Invalid input (body JSON sai) |
69 | Wrong game state — chưa /gameplay, đang FS mà đổi bet |
1000 | Popup error (message i18n, buy không hợp lệ) |
4. Grid & symbol
Mọi board (init_reels, win_result[].reels, cheat reels) đều là mảng cột:
reels[col][row] // col 0..6 trái → phải; row 0..6 trên → dưới multipliers[col][row] // sticky count; display = 2^(count-1) khi count ≥ 1
6
1
2
3
4
5
7
0
0
1
2
3
4
5
0
0
0
6
1
2
3
4
5
6
1
2
3
4
5
6
1
2
3
4
5
6
1
2
3
4
5
6
1
2
3
4
5
6
1
Hàng đầu = row 0. Ô vàng viền = cluster Lollipop (0) thắng. Ô scatter (7) góc trên phải.
| id | Symbol | Pay? |
|---|---|---|
| 0 | Lollipop | Có |
| 1 | Heart | Có |
| 2 | JellyBean | Có |
| 3 | Star | Có |
| 4 | GreenBear | Có |
| 5 | BlueBear | Có |
| 6 | OrangeBear | Có |
| 7 | Scatter | Không pay — trigger FS |
Luôn dùng pay_table từ /gameplay. Line win = round(bet × multiplier × bonus_multiplier). bonus_multiplier lấy từ sticky trên các ô của cluster.
5. GET /api/v1/gameplay
Gọi 1 lần khi vào game. Thiếu bước này thì POST /spins trả code 69.
GET /api/v1/gameplay
| Field | Type | Client dùng để |
|---|---|---|
init_reels | int[7][7] | Board preview idle |
user_money | int64 | Chip hiện tại |
bet | int64 | Bet đang chọn trên server |
bets | int64[] | Các mức bet hợp lệ |
show_bets | int64[] | Giá trị hiển thị UI (cùng index) |
pay_table | float[][] | Bảng trả thưởng |
is_free_spin | bool | Đang FS → restore UI, disable đổi bet / buy |
free_spins | int | Số FS còn lại |
max_free_spins | int | Mốc max thanh FS |
free_spin_pot | int64 | Tổng win đang cộng dồn (chưa credit) |
free_spin_type | int | 0 / 1 / 2 |
multipliers | int[7][7] | Sticky count từng ô — restore overlay |
buy_free_spins_price | int64 | Hệ số giá buy FS |
buy_super_free_spins_price | int64 | Hệ số giá buy Super FS |
{
"code": 0,
"msg": {
"init_reels": [[6,1,2,3,4,5,6],[1,0,0,2,3,4,5],[2,0,0,0,1,2,3],[3,4,5,6,1,2,3],[4,5,6,1,2,3,4],[5,6,1,2,3,4,5],[7,1,2,3,4,5,6]],
"user_money": 500000,
"bet": 1000,
"bets": [200, 1000, 2000, 10000],
"show_bets": [200, 1000, 2000, 10000],
"pay_table": [[50,20,10],[25,10,5],[15,8,4],[10,5,2],[8,3,1.5],[5,2,1],[3,1.5,0.8]],
"is_free_spin": false,
"free_spins": 0,
"max_free_spins": 0,
"free_spin_pot": 0,
"free_spin_type": 0,
"multipliers": [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]],
"buy_free_spins_price": 100,
"buy_super_free_spins_price": 200
}
}
6. POST /api/v1/spins
POST /api/v1/spins
{ "bet": 1000 }
- Phải gọi
/gameplaytrước. - Base: trừ
betngay. FS: không trừ, vẫn gửibet(server bỏ qua đổi bet). reelschỉ dùng cheat non-prod.
SpinResult
| Field | Type | Ý nghĩa |
|---|---|---|
bet | int64 | Bet server đang dùng |
price | int64 | 0 spin thường; giá đã trừ nếu từ buy |
user_money | int64 | Chip sau giao dịch response này |
win_amount | int64 | Base: win đã credit. FS giữa chừng: win spin (chưa vào chip). FS xong: cả pot |
is_free_spin | bool | Spin vừa rồi nằm trong FS |
free_spins | int | Số FS còn lại — source of truth |
free_spin_pot | int64 | Pot sau spin. = 0 khi FS kết thúc |
is_finish_free_spin | bool | Spin FS cuối. Credit pot vào user_money |
is_bonus_free_spin | bool | Vừa award thêm FS |
number_of_bonus_free_spins | int | +N cho popup |
free_spin_type | int | 0 / 1 / 2 |
max_free_spins | int | Max thanh progress |
win_result | WinResult[] | Chuỗi tumble, play tuần tự |
WinResult / WinLine
| Field | Ý nghĩa |
|---|---|
reels | Board trước khi xóa ô thắng bước này |
lines | Cụm thắng. Rỗng = tumble dừng |
positions | positions[col] = [row, ...] mọi ô thắng |
multipliers | Sticky count cùng index với reels |
win_amount | Tổng line win bước này |
total_win_amount | Cộng dồn từ đầu spin tới bước này |
lines[].symbol | 0–6 |
lines[].positions | Ô thuộc cluster |
lines[].line_size | Số ô cùng symbol |
lines[].multiplier | Hệ số paytable |
lines[].bonus_multiplier | Sticky nhân thêm |
lines[].win_amount | Chip của cluster |
{
"code": 0,
"msg": {
"bet": 1000, "price": 0, "user_money": 509000, "win_amount": 10000,
"is_free_spin": false, "free_spins": 10, "free_spin_pot": 0,
"is_finish_free_spin": false, "is_bonus_free_spin": true,
"number_of_bonus_free_spins": 10, "free_spin_type": 1, "max_free_spins": 10,
"win_result": [{
"lines": [{ "symbol": 0, "positions": [[1,2],[1,2],[1,2],[],[],[],[]], "win_amount": 10000, "line_size": 5, "multiplier": 10, "bonus_multiplier": 1 }],
"reels": [[6,1,2,3,4,5,6],[1,0,0,2,3,4,5],[2,0,0,0,1,2,3],[3,4,5,6,1,2,3],[4,5,6,1,2,3,4],[5,6,1,2,3,4,5],[7,7,7,3,4,5,6]],
"win_amount": 10000, "total_win_amount": 10000,
"multipliers": [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]],
"positions": [[1,2],[1,2],[1,2],[],[],[],[]]
}]
}
}
7. POST /buy-freespins & /buy-super-freespins
POST /api/v1/buy-freespins
{ "bet": 1000 }
POST /api/v1/buy-super-freespins
{ "bet": 1000 }
- Giá FS =
buy_free_spins_price × bet. Super =buy_super_free_spins_price × bet. - Cấm khi đang FS → popup code 1000.
- Response cùng shape
SpinResult:price= chip đã trừ, guaranteed scatter trigger FS. - Super: mọi ô seed sticky count = 2 → display ×2 ngay từ đầu.
Nút Buy chỉ enable khi
!is_free_spin và đủ chip theo giá × bet.{
"code": 0,
"msg": {
"bet": 1000, "price": 200000, "user_money": 300000, "win_amount": 0,
"is_free_spin": false, "free_spins": 10, "free_spin_pot": 0,
"is_finish_free_spin": false, "is_bonus_free_spin": true,
"number_of_bonus_free_spins": 10, "free_spin_type": 2, "max_free_spins": 10,
"win_result": []
}
}
8. Tumble / sticky / animation
- Với mỗi
win_result[i]: vẽreels+ overlay sticky từmultipliers. - Nếu
lines.length > 0: highlight cluster, cộngwin_amountvào counter. - Xóa ô thắng. Gravity theo cột (row lớn = dưới). Fill từ trên (row 0).
- Board mới =
win_result[i+1].reels. Đừng tự random. - Phần tử cuối thường
lines = []: hết tumble. - Sticky display =
2^(count-1). Count 1 → ×1, count 2 → ×2, count 3 → ×4, count 4 → ×8…
Scatter không bị xóa khi paying symbol thắng. Chúng ở lại và rơi theo gravity.
9. Free spins
| Scatter | Award |
|---|---|
| 3 | +10 FS |
| 4 | +12 FS |
| 5 | +15 FS |
| 6 | +20 FS |
| ≥7 | +30 FS |
- Spin trigger không set
is_free_spin. Win spin đó credit ngay. - Các spin FS: không trừ bet. Win cộng
free_spin_pot, chưa cộng chip tới spin cuối. - Spin cuối:
is_finish_free_spin = true,win_amount= cả pot,user_moneyđã cộng pot. - Giữa FS: disable đổi bet và cả hai nút buy.
10. Cheat (chỉ non-prod / cheater)
{
"bet": 1000,
"reels": [
[0,0,1,2,3,4,5],[0,0,0,1,2,3,4],[0,0,0,6,1,2,3],
[4,5,6,1,2,3,4],[5,6,1,2,3,4,5],[6,1,2,3,4,5,6],[7,7,7,1,2,3,4]
]
}
Đủ 7 cột, mỗi cột 7 hàng. Production: field bị bỏ qua, luôn random.
11. Error & tiền
| Tình huống | Hành vi client |
|---|---|
| HTTP 401 | Token hết hạn — relogin |
| code 69 | Gọi lại GET /gameplay, sync state |
| code 1000 | Hiện popup msg (string i18n) |
| code -1 khi spin/buy | Hết tiền hoặc lỗi nội bộ — refresh qua /gameplay |
| Spin khi user đang room PvP | HTTP 400 body "blocked" |
| Event | Chip |
|---|---|
| Base spin | −bet ngay; +win_amount nếu thắng |
| Buy FS / Super | −price ngay |
| FS giữa chừng | Không đổi. Chỉ tăng free_spin_pot |
| FS kết thúc | +pot vào user_money |
12. Checklist client
- Vào game:
GET /gameplaytrước mọi spin. - Board luôn
[col][row], 7×7, row 0 = top. - Play tuần tự
win_result; tumble gravity; đừng tự gen symbol. - Sticky overlay =
2^(multipliers[col][row]-1). - Bet chỉ gửi giá trị trong
bets. - Giá buy = price field × bet. Super seed ×2 mọi ô.
- FS: khóa bet/buy; tin
free_spins; credit chip chỉ khiis_finish_free_spin. - Restore: nếu
/gameplaytrảis_free_spin, nhảy thẳng FS UI kèm sticky. - Không gọi song song 2 spin cho 1 user.