diff --git a/www/html/Admin/private/store.json b/www/html/Admin/private/store.json
index 92bc6fb..48d9fa8 100644
--- a/www/html/Admin/private/store.json
+++ b/www/html/Admin/private/store.json
@@ -51,9 +51,9 @@
"providerUserId": "p_1775109142385_wq7wfy1p32j",
"notes": "auto: player-coins",
"blocked": false,
- "coins": 945,
+ "coins": 953,
"createdAt": "2026-04-02T05:52:21+00:00",
- "updatedAt": "2026-06-22T16:52:22+00:00",
+ "updatedAt": "2026-06-22T17:14:58+00:00",
"daily": {
"anchorMs": 1781197200000,
"claimedDays": [
@@ -67,7 +67,7 @@
],
"lockUntilMs": 0
},
- "score": 840,
+ "score": 848,
"scoreByCase": {
"1": 16,
"10": 320,
@@ -76,7 +76,7 @@
"13": 40,
"14": 20,
"9": 40,
- "12": 108,
+ "12": 116,
"15": 20,
"4": 10,
"5": 20,
@@ -150,18 +150,18 @@
"providerUserId": "p_1778099867825_vd4pphrr5a",
"notes": "auto: player-coins",
"blocked": false,
- "coins": 72,
+ "coins": 82,
"createdAt": "2026-05-06T20:37:46+00:00",
- "updatedAt": "2026-06-22T17:04:52+00:00",
+ "updatedAt": "2026-06-22T17:14:58+00:00",
"lobbyColorThemeIndex": 5,
"lobbySkinToneIndex": 1,
- "score": 72,
+ "score": 82,
"scoreByCase": {
- "12": 72
+ "12": 82
},
"lbName": "MONE",
"achievements": {
- "d1_minigame_solver": 9
+ "d1_minigame_solver": 10
}
},
{
diff --git a/www/html/Game/data/game-timing.json b/www/html/Game/data/game-timing.json
index 9ab5ccd..8fc8934 100644
--- a/www/html/Game/data/game-timing.json
+++ b/www/html/Game/data/game-timing.json
@@ -89,9 +89,9 @@
"balloonBossPlayerBalloonFallbackUrl": "/Game/img/MegaVirus/Artboard%209.png",
"balloonBossBalloonsPerPlayer": 3,
"forcedMinigameKeys": [
- "quiz",
- "quiz_carry",
- "jump_survive"
+ "jump_survive",
+ "space_shooter",
+ "balloon_boss"
],
"testSpecialCardByMap": {},
"troublesomeForceOffer": false,
diff --git a/www/html/Game/public/js/play.js b/www/html/Game/public/js/play.js
index 58eba2c..322ef28 100644
--- a/www/html/Game/public/js/play.js
+++ b/www/html/Game/public/js/play.js
@@ -16704,9 +16704,12 @@
if (balloonBossGameEnded) return;
try {
if (socket && myId != null && isMePlayHost()) {
- /* แนบตารางคะแนนสุดท้าย (host authoritative) → ทุกเครื่องโชว์อันดับ/คะแนนตรงกัน */
+ /* แนบตารางคะแนน + สถานะตาย/รอดสุดท้าย (host authoritative) → ทุกเครื่องโชว์อันดับ/คะแนน/โบนัสผู้รอดตรงกัน
+ (เดิมส่งแค่ score ไม่มี eliminated → client ที่บอท/คนตายไม่ sync ได้โบนัสผู้รอด +10 เกิน = คะแนนจบไม่ตรง) */
const scores = buildStableShipParticipantRefsPlay().map((e) => ({
- id: e.id, score: Math.max(0, (e.ref && (e.ref.balloonBossScore | 0)) || 0),
+ id: e.id,
+ score: Math.max(0, (e.ref && (e.ref.balloonBossScore | 0)) || 0),
+ eliminated: !!(e.ref && e.ref.balloonBossEliminated),
}));
socket.emit('balloon-boss-over', { reason: reason, scores: scores });
}
@@ -16966,7 +16969,9 @@
const ent = entry.ref;
if (!ent || ent.balloonBossCx == null) continue;
if (String(entry.id) === String(b.ownerId)) continue;
- const canBalloonHit = isPreviewBotId(entry.id) || ent === me;
+ /* ลูกโป่งของตัวเอง = เจ้าตัวตัดสิน · บอท = host ตัดสินคนเดียว (non-host เอาตาย/ลูกโป่งจาก fill-bot-state)
+ เดิม non-host คิด damage บอทเองจากกระสุนที่ relay มา → บอทตายคนละจังหวะ 2 จอ */
+ const canBalloonHit = (ent === me) || (isPreviewBotId(entry.id) && isMePlayHost());
if (!canBalloonHit) continue;
const cc = balloonBossBalloonClusterWorldPlay(ent, bossC.cx, bossC.cy);
const pdx = b.x - cc.cx, pdy = b.y - cc.cy;
@@ -19473,8 +19478,9 @@
d.scores.forEach((s) => {
if (!s || s.id == null) return;
const sc = Math.max(0, Number(s.score) || 0);
- if (myId != null && String(s.id) === String(myId)) me.balloonBossScore = sc;
- else { const o = others.get(String(s.id)) || others.get(s.id); if (o) o.balloonBossScore = sc; }
+ const elim = !!s.eliminated; /* sync สถานะตาย/รอดจาก host → โบนัสผู้รอด/อันดับตรงกัน (กันได้ +10 เกิน) */
+ if (myId != null && String(s.id) === String(myId)) { me.balloonBossScore = sc; me.balloonBossEliminated = elim; }
+ else { const o = others.get(String(s.id)) || others.get(s.id); if (o) { o.balloonBossScore = sc; o.balloonBossEliminated = elim; } }
});
}
endBalloonBossGame(reason);
diff --git a/www/html/Game/server.js b/www/html/Game/server.js
index c4e7533..a94f83b 100644
--- a/www/html/Game/server.js
+++ b/www/html/Game/server.js
@@ -7892,7 +7892,7 @@ io.on('connection', (socket) => {
if (!space || !data) return;
const reason = (data.reason === 'victory' || data.reason === 'all_dead') ? data.reason : 'all_dead';
const scores = Array.isArray(data.scores)
- ? data.scores.filter((s) => s && s.id != null).map((s) => ({ id: s.id, score: Math.max(0, Number(s.score) || 0) }))
+ ? data.scores.filter((s) => s && s.id != null).map((s) => ({ id: s.id, score: Math.max(0, Number(s.score) || 0), eliminated: !!s.eliminated }))
: [];
socket.to(sid).emit('balloon-boss-over', { reason, scores });
});