Let daemon gameplay state close the main menu

This commit is contained in:
Meta Vens 2026-07-20 05:22:39 +01:00
commit ab6face8e2
4 changed files with 16 additions and 3 deletions

View file

@ -3791,6 +3791,10 @@ internal sealed class AetheriaDaemonYmirSmokeChecks
node.Id is "aetheria.daemon.game.frame" or "aetheria.daemon.game.player" or "aetheria.daemon.game.commands")
.All(node => node.Layout.TryGetValue("display", out var display) && display == "none"),
"operator diagnostics must remain published state without becoming pilot-camera UI");
var mainMenu = Flatten(surface.Surface.Root).Single(node => node.Id == "aetheria.daemon.game.main_menu");
Require(mainMenu.Layout.TryGetValue("display", out var menuDisplay) && menuDisplay == "none" &&
mainMenu.EmbeddedDocuments.Count == 0,
"an active pilot surface must not embed or display the main menu until daemon menu state opens it");
}
private static void ChargedWeaponCannotBypassChargeLifecycle()

View file

@ -1935,8 +1935,13 @@ static async Task PublishClientGameplayDocumentsAsync(
var mainMenuState = await node.MutableDocument<AetheriaMainMenuState>(AetheriaStateNode.MainMenuStateKey)
.ReadAsync()
.ConfigureAwait(false);
var hasActivePilot = !string.IsNullOrWhiteSpace(result.Frame.Run?.CurrentEntityKey) &&
result.Frame.Run.Zones?.Any(zone =>
zone != null &&
zone.ZoneIndex == result.Frame.Run.CurrentZoneIndex &&
(zone.Entities?.Count ?? 0) > 0) == true;
var activeMainMenuSurfaceId = string.IsNullOrWhiteSpace(mainMenuState?.ActiveSurfaceId)
? AetheriaRuntimeMainMenuCommands.RootSurfaceId
? (hasActivePilot ? "" : AetheriaRuntimeMainMenuCommands.RootSurfaceId)
: mainMenuState.ActiveSurfaceId;
var reactiveGameSurface = AetheriaRuntimeSurfaceDocuments.ToPortableSurface(
AetheriaRuntimeDaemonGameSurfaceBuilder.BuildReactiveGameplay(

View file

@ -405,6 +405,7 @@ public static class AetheriaEveCommandBridge
case AetheriaRuntimeEveCommandKind.MainMenuBackToMain:
case AetheriaRuntimeEveCommandKind.MainMenuContinueRun:
case AetheriaRuntimeEveCommandKind.MainMenuNewGame:
return "";
case AetheriaRuntimeEveCommandKind.MainMenuQuit:
return AetheriaRuntimeMainMenuCommands.RootSurfaceId;
default:

View file

@ -19,7 +19,7 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimeDaemonFrameDocument frame,
AetheriaRuntimeDaemonHealthDocument health,
AetheriaRuntimeDaemonCommandBoundaryDocument commandBoundary,
string activeMainMenuSurfaceId = AetheriaRuntimeMainMenuCommands.RootSurfaceId,
string activeMainMenuSurfaceId = "",
AetheriaRuntimeCatalogSnapshot? catalog = null)
{
frame ??= new AetheriaRuntimeDaemonFrameDocument();
@ -30,7 +30,8 @@ namespace GameCult.Aetheria.State.Verse
var entity = FindCurrentEntity(run, zone);
var target = FindTargetEntity(zone, entity);
var entityName = string.IsNullOrWhiteSpace(entity?.Name) ? "(no current entity)" : entity!.Name;
activeMainMenuSurfaceId = NormalizeMainMenuSurfaceId(activeMainMenuSurfaceId);
if (!string.IsNullOrWhiteSpace(activeMainMenuSurfaceId))
activeMainMenuSurfaceId = NormalizeMainMenuSurfaceId(activeMainMenuSurfaceId);
var surfaceChildren = new List<AetheriaRuntimeSurfaceComponent>
{
PlayableWorldSurface(
@ -1761,6 +1762,8 @@ namespace GameCult.Aetheria.State.Verse
string id,
string activeSurfaceId)
{
if (string.IsNullOrWhiteSpace(activeSurfaceId))
return Hidden(Node(id, "surface.slot", Array.Empty<(string Key, string Value)>()));
activeSurfaceId = NormalizeMainMenuSurfaceId(activeSurfaceId);
var activeSurfaceRecordRef = $"eve:surface:{activeSurfaceId}";
return new AetheriaRuntimeSurfaceComponent(