feat(entry): START GAME shows the wait-vs-drop-in choice for free games too

Previously the timing-choice modal (Start Now / Wait for Next Block) only appeared for
paid-credits players; free players got a silent immediate drop-in. Now it shows whenever
the game would start instantly:
- Server getGameModeInfo exposes freePlayEnabled (was server-only) so the client knows
  free play is available even on a paid instance.
- Client (inputHandler) gates the modal on free-play-available OR paid-credits-with-credits;
  the modal is purely a TIMING pick (auto_start vs join_queue) — payment method is unchanged.
- Modal cost text reflects free play.

Both waiting animations are untouched: they render on the ROT display via WaitingScreenAnimator
using the base GameTiles, independent of the render-kit packs (which are disabled for SP anyway),
so they work regardless of visualization style. Suite 62/435 green.
This commit is contained in:
jwinterm
2026-07-12 10:44:31 -04:00
parent 55374aaf3a
commit 31b4c3ca5d
3 changed files with 18 additions and 10 deletions
+10 -8
View File
@@ -201,20 +201,22 @@ const InputHandler = {
setupClickHandlers: function() {
// Add click handling for the HTML START button
$('#startButton').click(function(e) {
// If early entry is available and user has credits, show choice modal
// Show the wait-vs-drop-in TIMING choice whenever the game would start instantly (no
// upfront payment): free play (this instance allows it), a FREE instance, or paid-credits
// with credits in hand. The chosen payment method flows through auto_start / join_queue
// unchanged — this modal only picks WHEN you enter.
if (typeof SocketHandlers !== 'undefined') {
var isPaidCredits = SocketHandlers._gameMode === 'PAID_CREDITS';
var mode = SocketHandlers._gameMode;
var freeAvailable = SocketHandlers._freePlayEnabled || mode === 'FREE';
var hasCredits = SocketHandlers._creditsBalance >= (SocketHandlers._creditsPerGame || 1);
var earlyAllowed = SocketHandlers._earlyEntryConfig &&
SocketHandlers._earlyEntryConfig.enabled &&
SocketHandlers._earlyEntryConfig.allowInCreditsMode;
if (isPaidCredits && hasCredits && earlyAllowed) {
SocketHandlers.showEntryChoiceModal();
var instantStart = freeAvailable || (mode === 'PAID_CREDITS' && hasCredits);
if (instantStart) {
SocketHandlers.showEntryChoiceModal({ freeAvailable: freeAvailable, hasCredits: hasCredits });
return;
}
}
// Default: attempt immediate start
// Default: attempt immediate start (payment-required modes go through their own flow)
socket.emit('auto_start');
// Check if we should show waiting screen
+7 -2
View File
@@ -708,6 +708,7 @@ const SocketHandlers = {
// Store game mode and early entry config
SocketHandlers._gameMode = data.mode;
SocketHandlers._freePlayEnabled = !!data.freePlayEnabled;
SocketHandlers._earlyEntryConfig = data.earlyEntry || { enabled: false };
SocketHandlers._creditsPayoutsEnabled = !!data.creditsPayoutsEnabled;
SocketHandlers._directPayoutsEnabled = !!data.directPayoutsEnabled;
@@ -1693,11 +1694,15 @@ const SocketHandlers = {
// Entry Choice Modal
// =====================
showEntryChoiceModal: function() {
showEntryChoiceModal: function(opts) {
opts = opts || {};
// Remove any existing modal
$('#entryChoiceOverlay').remove();
var cost = this._creditsPerGame || 1;
var costText = opts.freeAvailable
? 'Free play — no credits needed'
: ('Cost: ' + cost + ' credit per game');
var $overlay = $('<div id="entryChoiceOverlay">').css({
position: 'fixed', top: 0, left: 0, width: '100%', height: '100%',
background: 'rgba(0,0,0,0.7)', zIndex: 3000,
@@ -1712,7 +1717,7 @@ const SocketHandlers = {
$modal.html(
'<div style="font-size:18px; font-weight:bold; margin-bottom:16px;">How do you want to enter?</div>' +
'<div style="font-size:12px; color:#888; margin-bottom:20px;">Cost: ' + cost + ' credit per game</div>' +
'<div style="font-size:12px; color:#888; margin-bottom:20px;">' + costText + '</div>' +
'<button id="entryChoiceNow" style="' +
'display:block; width:100%; padding:12px; margin-bottom:10px; cursor:pointer; ' +
'background:linear-gradient(180deg,#662200,#441100); border:2px solid #ff6600; ' +
+1
View File
@@ -1492,6 +1492,7 @@ class GameModeManager {
return {
mode: this.gameMode,
freePlayEnabled: !!this.freePlayEnabled, // players may choose free play even on a paid instance
cryptoType: this.cryptoType,
currencyLabel: this.currencyLabel, // sXMR on stagenet, XMR on mainnet, WOW for Wownero
gameName: this.gameName, // Monerogue / Wownerogue