From df65dbcb70546c7e18d53acc905512264db1e73d Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 28 Jun 2026 15:04:31 +0100 Subject: [PATCH] Route player HUD through managed sessions --- Aetheria.State.Verify/Program.cs | 48 +++++++++++++++++++ .../Runtime/AetheriaClientState.cs | 10 ++-- .../Runtime/AetheriaRuntimePlayerHudState.cs | 13 +++-- 3 files changed, 59 insertions(+), 12 deletions(-) diff --git a/Aetheria.State.Verify/Program.cs b/Aetheria.State.Verify/Program.cs index 19a26694a..bc09a1510 100644 --- a/Aetheria.State.Verify/Program.cs +++ b/Aetheria.State.Verify/Program.cs @@ -7294,6 +7294,12 @@ static void RequireUnitySharedDocumentAccessorErgonomics(string root) "UI", "HUD", "SchematicDisplay.cs")); + var playerHudState = File.ReadAllText(Path.Combine( + root, + "Packages", + "org.gamecult.aetheria.state", + "Runtime", + "AetheriaRuntimePlayerHudState.cs")); var requiredSchematicDisplaySymbols = new[] { "AetheriaRuntimePlayerHudSession _playerHud", @@ -7332,6 +7338,48 @@ static void RequireUnitySharedDocumentAccessorErgonomics(string root) string.Join(", ", schematicDisplayHits)); } + var requiredPlayerHudSessionSymbols = new[] + { + "private readonly AetheriaRuntimeCatalogSession _catalog;", + "private readonly AetheriaRuntimePlayerSettingsSession _playerSettings;", + "private readonly AetheriaRuntimeCurrentEntitySession _currentEntity;", + "public AetheriaRuntimePlayerHudSession(", + "AetheriaRuntimeCatalogSession catalog", + "AetheriaRuntimePlayerSettingsSession playerSettings", + "AetheriaRuntimeCurrentEntitySession currentEntity", + "public AetheriaRuntimeCatalogSnapshot? Catalog => _catalog.Current;", + "public AetheriaRuntimePlayerSettingsDocument? PlayerSettings => _playerSettings.Current;", + "public AetheriaRuntimeCurrentEntityDocument? CurrentEntity => _currentEntity.Current;" + }; + var missingPlayerHudSessionSymbols = requiredPlayerHudSessionSymbols + .Where(symbol => !playerHudState.Contains(symbol, StringComparison.Ordinal)) + .ToArray(); + if (missingPlayerHudSessionSymbols.Length > 0) + { + throw new InvalidOperationException( + "AetheriaRuntimePlayerHudSession must compose named managed sessions instead of owning raw reactive documents: " + + string.Join(", ", missingPlayerHudSessionSymbols)); + } + + if (playerHudState.Contains("CultMeshReactiveDocument<", StringComparison.Ordinal) || + playerHudState.Contains("using GameCult.Mesh;", StringComparison.Ordinal)) + { + throw new InvalidOperationException( + "AetheriaRuntimePlayerHudSession reintroduced raw CultMesh reactive document ownership."); + } + + if (!clientState.Contains("var catalog = ObserveCatalog(options);", StringComparison.Ordinal) || + !clientState.Contains("AetheriaRuntimePlayerSettingsSession? playerSettings = null;", StringComparison.Ordinal) || + !clientState.Contains("AetheriaRuntimeCurrentEntitySession? currentEntity = null;", StringComparison.Ordinal) || + !clientState.Contains("playerSettings = Settings.ObservePlayer(options);", StringComparison.Ordinal) || + !clientState.Contains("currentEntity = Current.ObserveEntity(options);", StringComparison.Ordinal) || + clientState.Contains("playerSettings = Settings.ReactivePlayer(options);", StringComparison.Ordinal) || + clientState.Contains("currentEntity = Current.ReactiveEntity(options);", StringComparison.Ordinal)) + { + throw new InvalidOperationException( + "AetheriaClientState.ObservePlayerHud() must compose named managed sessions instead of raw reactive CultMesh documents."); + } + var volumeCloudRenderer = File.ReadAllText(Path.Combine( root, "Assets", diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs index d35b848d7..33d98ad90 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaClientState.cs @@ -320,13 +320,13 @@ namespace GameCult.Aetheria.State.Verse public AetheriaRuntimePlayerHudSession ObservePlayerHud( CultMeshReactiveDocumentOptions? options = null) { - var catalog = ReactiveCatalog(options); - CultMeshReactiveDocument? playerSettings = null; - CultMeshReactiveDocument? currentEntity = null; + var catalog = ObserveCatalog(options); + AetheriaRuntimePlayerSettingsSession? playerSettings = null; + AetheriaRuntimeCurrentEntitySession? currentEntity = null; try { - playerSettings = Settings.ReactivePlayer(options); - currentEntity = Current.ReactiveEntity(options); + playerSettings = Settings.ObservePlayer(options); + currentEntity = Current.ObserveEntity(options); return new AetheriaRuntimePlayerHudSession(catalog, playerSettings, currentEntity); } catch diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimePlayerHudState.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimePlayerHudState.cs index 90f7d9694..753528f13 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimePlayerHudState.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimePlayerHudState.cs @@ -1,5 +1,4 @@ using System; -using GameCult.Mesh; #nullable enable @@ -7,14 +6,14 @@ namespace GameCult.Aetheria.State.Verse { public sealed class AetheriaRuntimePlayerHudSession : IDisposable { - private readonly CultMeshReactiveDocument _catalog; - private readonly CultMeshReactiveDocument _playerSettings; - private readonly CultMeshReactiveDocument _currentEntity; + private readonly AetheriaRuntimeCatalogSession _catalog; + private readonly AetheriaRuntimePlayerSettingsSession _playerSettings; + private readonly AetheriaRuntimeCurrentEntitySession _currentEntity; public AetheriaRuntimePlayerHudSession( - CultMeshReactiveDocument catalog, - CultMeshReactiveDocument playerSettings, - CultMeshReactiveDocument currentEntity) + AetheriaRuntimeCatalogSession catalog, + AetheriaRuntimePlayerSettingsSession playerSettings, + AetheriaRuntimeCurrentEntitySession currentEntity) { _catalog = catalog ?? throw new ArgumentNullException(nameof(catalog)); _playerSettings = playerSettings ?? throw new ArgumentNullException(nameof(playerSettings));