An abort during prep goes back to the menu, not the desktop

Cyd Alt+Q'ed out of a mission and landed on the desktop. From a RUNNING
race that was never the intent - the single-binary loop returns to the
setup screen whenever the console says the mission completed - but the
console only learned that from PhaseRunning. A mission that died while
still PREPPING - Alt+Q during loading, or during the commit hold - left
the console in PhaseWaiting forever, MissionCompleted() answered False,
and WinMain fell out of the race loop to the desktop.

The hole is as old as the race loop, but it had no traffic until tonight:
the commit hold makes the prep window somewhere players actually stand,
and changing your mind there is exactly what Alt+Q is for.

The console now counts a prep death as a completed mission: back to the
menu, lobby intact - a host lands on the setup page still hosting, the
commit board comes down, and the remote console channels close, which
ends the members' prep too (their consoles vanishing already means the
mission cannot start; now it means it promptly).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-08-11 22:57:00 -05:00
co-authored by Claude Opus 5
parent bc309f7919
commit 2d70ae7075
+26
View File
@@ -704,6 +704,32 @@ namespace
switch (gPhase)
{
case PhaseWaiting:
//
// A mission can die before it ever runs - Alt+Q during the
// commit hold, or while loading. The console only learned a
// mission was over from PhaseRunning, so an abort during prep
// left it in PhaseWaiting forever, MissionCompleted() answered
// False, and WinMain's single-binary loop fell out to the
// DESKTOP instead of returning to the setup screen. The commit
// hold makes the prep window somewhere players actually stand,
// so the hole finally had traffic. A prep death counts as a
// completed mission now: back to the menu, lobby intact.
//
if (state == Application::EndingMission ||
state == Application::StoppingMission ||
state == Application::AbortingMission)
{
DEBUG_STREAM << "LocalConsole: mission ended during prep - "
<< "back to the menu\n" << std::flush;
InterlockedExchange(&gMissionRunning, 0);
gPhase = PhaseStopped;
DestroyStatusBoard();
if (gNetworkRace)
{
DisconnectRemotes();
}
break;
}
if (gNetworkRace)
{
MarshalRemotes();