From a8a6da6760ad6ddeffeed9c52f4829819703d70d Mon Sep 17 00:00:00 2001 From: arcattack Date: Thu, 23 Jul 2026 15:00:41 -0500 Subject: [PATCH] Solo mission clock: end the mission when the game length expires (port shim) Field 2026-07-23: a 20-minute solo mission was still running at 53 minutes. In the arcade the OPERATOR CONSOLE owned the game clock and sent StopMission at zero; the engine only computes the HUD countdown (secondsRemainingInGame) -- nothing consumes it. The desktop FE-solo mode has no console, so timed solo missions ran forever. Shim at the countdown site (Application::Execute): when no console/relay owns the session (BT_RELAY unset), post the console's own StopMissionMessage when the clock runs out -- the normal end flow (EndingMission -> review -> FE relaunch) takes over. length=0 (raw solo) stays endless; console-driven sessions untouched. One-shot latch resets outside RunningMission. Awaiting live verification (a 60s-length solo egg must end itself). Co-Authored-By: Claude Opus 4.8 (1M context) --- engine/MUNGA/APP.cpp | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/engine/MUNGA/APP.cpp b/engine/MUNGA/APP.cpp index fd33383..792aad9 100644 --- a/engine/MUNGA/APP.cpp +++ b/engine/MUNGA/APP.cpp @@ -662,10 +662,37 @@ Time endIntercom = Now(); // Execution statistics //-------------------------------------------------------------------------- // - if (GetApplicationState() == RunningMission) { - secondsRemainingInGame = - currentMission->GetGameLength() - (Now() - gameStarted); + // SOLO mission clock (port shim, 2026-07-23): in the arcade the OPERATOR + // CONSOLE owned the game clock and sent StopMission at zero -- the engine + // only computes this HUD countdown; NOTHING consumes it. The desktop + // FE-solo mode has no console, so a timed solo mission ran FOREVER + // (field: a 20-min mission still live at 53 min). When no console/relay + // owns the session (BT_RELAY unset), post the console's own end message + // when the clock runs out. length=0 (raw solo) stays endless; + // console-driven sessions are untouched (the relay ends them). + static int s_soloClockFired = 0; + if (GetApplicationState() == RunningMission) + { + secondsRemainingInGame = + currentMission->GetGameLength() - (Now() - gameStarted); + + if (currentMission->GetGameLength() > 0.0f + && secondsRemainingInGame <= 0.0f + && !s_soloClockFired + && getenv("BT_RELAY") == 0) + { + s_soloClockFired = 1; + DEBUG_STREAM << "[mission] solo game clock expired (" + << currentMission->GetGameLength() + << "s) -- ending the mission" << std::endl << std::flush; + StopMissionMessage stop_message(0); + Time when = Now(); + Post(HighEventPriority, this, &stop_message, when); + } + } + else + s_soloClockFired = 0; } routePacketFinished = False;