From c0670fd07c0f707c055a3bd5f49e9920eff57795 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Mon, 20 Jul 2026 05:06:23 +0100 Subject: [PATCH 1/3] Pin visibly themed Eve cockpit release --- ReleaseConsumerProject/Packages/manifest.json | 2 +- ReleaseConsumerProject/Packages/packages-lock.json | 4 ++-- scripts/run-aetheria-daemon-world-witness.ps1 | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ReleaseConsumerProject/Packages/manifest.json b/ReleaseConsumerProject/Packages/manifest.json index 29c8b9c..63ad8ae 100644 --- a/ReleaseConsumerProject/Packages/manifest.json +++ b/ReleaseConsumerProject/Packages/manifest.json @@ -9,7 +9,7 @@ "org.gamecult.cultlib": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.43", "org.gamecult.eve.plugin-fields": "https://github.com/GameCult/EvePlugins.git?path=/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields#eve-plugin-fields-unity-v0.2.3", "org.gamecult.eve.surface": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.surface#eveunity-surface-v0.2.4", - "org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.102", + "org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.103", "org.gamecult.eve.unity-uitoolkit": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-uitoolkit#eveunity-uitoolkit-v0.1.2" }, "testables": [ diff --git a/ReleaseConsumerProject/Packages/packages-lock.json b/ReleaseConsumerProject/Packages/packages-lock.json index 9ad97d9..111ca84 100644 --- a/ReleaseConsumerProject/Packages/packages-lock.json +++ b/ReleaseConsumerProject/Packages/packages-lock.json @@ -144,7 +144,7 @@ "hash": "e08fa08335f99e9edddeb706912eecfad07cb281" }, "org.gamecult.eve.unity-scene": { - "version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.102", + "version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.103", "depth": 0, "source": "git", "dependencies": { @@ -156,7 +156,7 @@ "com.unity.render-pipelines.universal": "17.4.0", "com.unity.modules.particlesystem": "1.0.0" }, - "hash": "ddd2c5871f935978a0640d43cb58e18579523125" + "hash": "050b2019bd6faa4275013516870d1ded245ee391" }, "org.gamecult.eve.unity-uitoolkit": { "version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-uitoolkit#eveunity-uitoolkit-v0.1.2", diff --git a/scripts/run-aetheria-daemon-world-witness.ps1 b/scripts/run-aetheria-daemon-world-witness.ps1 index 25aa7cb..6cf8b63 100644 --- a/scripts/run-aetheria-daemon-world-witness.ps1 +++ b/scripts/run-aetheria-daemon-world-witness.ps1 @@ -17,7 +17,7 @@ param( ) $ErrorActionPreference = "Stop" -$expectedEveUnityCommit = "ddd2c5871f935978a0640d43cb58e18579523125" +$expectedEveUnityCommit = "050b2019bd6faa4275013516870d1ded245ee391" $expectedEveFieldsCommit = "c5a4a75c1b727499b16c2dae1895f29e2a9f72f0" $expectedEveUnityUiToolkitCommit = "44390549775ec535ee31fc60a5bc594f372f4147" $expectedCultLibCommit = "f67f5122ed1bd11da016e7b820ed60145ccd0299" From 8d0789ba0d9a9fe0589c3ed3665975104a723e3d Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Mon, 20 Jul 2026 05:22:52 +0100 Subject: [PATCH 2/3] Witness the mounted provider cockpit --- .../PlayMode/GenericWorldCaptureTests.cs | 19 +++++++++++++------ .../PlayMode/GenericWorldCaptureTests.cs | 19 +++++++++++++------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/ReleaseConsumerProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs b/ReleaseConsumerProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs index 8cb8b1d..1bcf65e 100644 --- a/ReleaseConsumerProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs +++ b/ReleaseConsumerProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs @@ -331,15 +331,19 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests provider, provider); host.Connect(); - var loweredSurface = new EveUiToolkitSurfaceLowerer().Lower( - provider.CurrentDocument.SurfaceDocument, - provider.Submit); - var cockpit = loweredSurface.Q("aetheria.daemon.game.cockpit"); + var mountedOverlay = root.GetComponent(); + Assert.That(mountedOverlay, Is.Not.Null); + var cockpit = mountedOverlay.Root.Q("aetheria.daemon.game.cockpit"); Assert.That(cockpit, Is.Not.Null, "The provider did not publish a generic cockpit overlay."); cockpitProgressCount = cockpit.Query().ToList().Count; Assert.That(cockpitProgressCount, Is.GreaterThanOrEqualTo(7)); - Assert.That(loweredSurface.Q("aetheria.daemon.game.frame").style.display.value, - Is.EqualTo(DisplayStyle.None), "Daemon diagnostics leaked into the pilot UI."); + Assert.That(mountedOverlay.Root.Q("aetheria.daemon.game.frame").style.display.value, + Is.EqualTo(DisplayStyle.None), "Daemon diagnostics leaked into the mounted pilot UI."); + Assert.That(mountedOverlay.Root.Q("aetheria.daemon.game.main_menu").style.display.value, + Is.EqualTo(DisplayStyle.None), "The closed main menu leaked into the mounted pilot UI."); + Assert.That(provider.CurrentDocument.SurfaceDocument.Surface.Root.Children + .Single(component => component.Id == "aetheria.daemon.game.frame").Layout["display"], + Is.EqualTo("none"), "Daemon diagnostics leaked into the pilot UI."); trajectories = root.GetComponent(); Assert.That(trajectories, Is.Not.Null); host.ShotAvailable += shot => @@ -956,6 +960,9 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests Assert.That(captureFieldVolume.CompositeCount - initialCompositeCount, Is.GreaterThanOrEqualTo(temporalSettlingFrames), "The pilot capture ran before the advertised temporal reconstruction had settled."); + Assert.That(cockpit.resolvedStyle.display, Is.Not.EqualTo(DisplayStyle.None)); + Assert.That(cockpit.worldBound.width, Is.GreaterThan(0), + "The mounted provider cockpit has no visible screen layout."); Debug.Log($"EveUnity witness phase temporal-settling-128-frames took {temporalSettlingElapsed.Elapsed.TotalMilliseconds:0.###}ms."); var pilotCaptureElapsed = Stopwatch.StartNew(); yield return null; diff --git a/TestProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs b/TestProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs index 8cb8b1d..1bcf65e 100644 --- a/TestProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs +++ b/TestProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs @@ -331,15 +331,19 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests provider, provider); host.Connect(); - var loweredSurface = new EveUiToolkitSurfaceLowerer().Lower( - provider.CurrentDocument.SurfaceDocument, - provider.Submit); - var cockpit = loweredSurface.Q("aetheria.daemon.game.cockpit"); + var mountedOverlay = root.GetComponent(); + Assert.That(mountedOverlay, Is.Not.Null); + var cockpit = mountedOverlay.Root.Q("aetheria.daemon.game.cockpit"); Assert.That(cockpit, Is.Not.Null, "The provider did not publish a generic cockpit overlay."); cockpitProgressCount = cockpit.Query().ToList().Count; Assert.That(cockpitProgressCount, Is.GreaterThanOrEqualTo(7)); - Assert.That(loweredSurface.Q("aetheria.daemon.game.frame").style.display.value, - Is.EqualTo(DisplayStyle.None), "Daemon diagnostics leaked into the pilot UI."); + Assert.That(mountedOverlay.Root.Q("aetheria.daemon.game.frame").style.display.value, + Is.EqualTo(DisplayStyle.None), "Daemon diagnostics leaked into the mounted pilot UI."); + Assert.That(mountedOverlay.Root.Q("aetheria.daemon.game.main_menu").style.display.value, + Is.EqualTo(DisplayStyle.None), "The closed main menu leaked into the mounted pilot UI."); + Assert.That(provider.CurrentDocument.SurfaceDocument.Surface.Root.Children + .Single(component => component.Id == "aetheria.daemon.game.frame").Layout["display"], + Is.EqualTo("none"), "Daemon diagnostics leaked into the pilot UI."); trajectories = root.GetComponent(); Assert.That(trajectories, Is.Not.Null); host.ShotAvailable += shot => @@ -956,6 +960,9 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests Assert.That(captureFieldVolume.CompositeCount - initialCompositeCount, Is.GreaterThanOrEqualTo(temporalSettlingFrames), "The pilot capture ran before the advertised temporal reconstruction had settled."); + Assert.That(cockpit.resolvedStyle.display, Is.Not.EqualTo(DisplayStyle.None)); + Assert.That(cockpit.worldBound.width, Is.GreaterThan(0), + "The mounted provider cockpit has no visible screen layout."); Debug.Log($"EveUnity witness phase temporal-settling-128-frames took {temporalSettlingElapsed.Elapsed.TotalMilliseconds:0.###}ms."); var pilotCaptureElapsed = Stopwatch.StartNew(); yield return null; From e5556c31943e0abe14a47e3419a4cc995ba43a47 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 22 Jul 2026 01:02:30 +0100 Subject: [PATCH 3/3] Keep live entity transforms body-owned --- .../Runtime/EveUnityPlayableWorldPresenter.cs | 24 ++++++++++- .../Runtime/EveUnityPlayableWorldRuntime.cs | 5 ++- .../EveUnitySceneSurfaceLowererTests.cs | 40 ++++++++++++++++++- .../org.gamecult.eve.unity-scene/package.json | 2 +- 4 files changed, 65 insertions(+), 6 deletions(-) diff --git a/packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldPresenter.cs b/packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldPresenter.cs index b77695b..e6a8b29 100644 --- a/packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldPresenter.cs +++ b/packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldPresenter.cs @@ -23,14 +23,17 @@ namespace GameCult.Eve.UnityScene { private readonly IEveUnityPlayableWorldSceneSink _sceneSink; private readonly IEveUnityPlayableWorldAssetResolver _assetResolver; + private readonly bool _liveEntityBodyOwner; private readonly HashSet _knownEntityIds = new HashSet(StringComparer.Ordinal); public EveUnityPlayableWorldPresenter( IEveUnityPlayableWorldSceneSink sceneSink, - IEveUnityPlayableWorldAssetResolver assetResolver) + IEveUnityPlayableWorldAssetResolver assetResolver, + bool liveEntityBodyOwner = false) { _sceneSink = sceneSink ?? throw new ArgumentNullException(nameof(sceneSink)); _assetResolver = assetResolver ?? throw new ArgumentNullException(nameof(assetResolver)); + _liveEntityBodyOwner = liveEntityBodyOwner; } public EveUnityPlayableWorldPresentation Apply(EveUnitySceneProjection projection) @@ -46,9 +49,26 @@ namespace GameCult.Eve.UnityScene { if (world == null) throw new ArgumentNullException(nameof(world)); - var nextEntityIds = new HashSet(StringComparer.Ordinal); _sceneSink.ConfigureWorld(world); + // A world that advertises a live entity body has one transform and + // membership owner: the SoA generation presenter. The durable Eve + // surface remains configuration/topology and must not periodically + // overwrite realtime body state. + if (_liveEntityBodyOwner && + (!string.IsNullOrWhiteSpace(world.EntityViewPointerId) || + !string.IsNullOrWhiteSpace(world.EntityBodyId))) + return new EveUnityPlayableWorldPresentation( + world.WorldRootId, + world.PlayerEntityId, + world.InputProfile, + world.CameraRig, + 0, + 0, + _knownEntityIds.Count); + + var nextEntityIds = new HashSet(StringComparer.Ordinal); + var upserted = 0; foreach (var entity in world.Entities) { diff --git a/packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs b/packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs index 94ca473..d0b2c43 100644 --- a/packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs +++ b/packages/org.gamecult.eve.unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs @@ -41,7 +41,10 @@ namespace GameCult.Eve.UnityScene _connection = new EveUnitySceneProviderConnection(_surfaceSource, commandSink); _client = new EveUnityPlayableWorldLiveClient( _connection, - new EveUnityPlayableWorldPresenter(sceneSink, assetResolver ?? new EveUnityAssetRefResolver()), + new EveUnityPlayableWorldPresenter( + sceneSink, + assetResolver ?? new EveUnityAssetRefResolver(), + liveEntityBodyOwner: _entityViews != null), receiptSource); if (assetManifestDocuments != null) diff --git a/packages/org.gamecult.eve.unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs b/packages/org.gamecult.eve.unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs index a65771c..356809a 100644 --- a/packages/org.gamecult.eve.unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs +++ b/packages/org.gamecult.eve.unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs @@ -1856,7 +1856,7 @@ namespace GameCult.Eve.UnityScene.Tests var presenter = new EveUnityPlayableWorldPresenter(sink, new EveUnityAssetRefResolver()); var firstProjection = lowerer.Lower(PlayableArpgDocument(), Advertisement("aetheria.daemon.game")); - var firstPresentation = presenter.Apply(firstProjection); + var firstPresentation = presenter.Apply(SnapshotWorld(firstProjection.PlayableWorld!)); Assert.That(firstPresentation.WorldRootId, Is.EqualTo("aetheria.daemon.game.playable")); Assert.That(firstPresentation.PlayerEntityId, Is.EqualTo("player-vanguard")); @@ -1875,7 +1875,7 @@ namespace GameCult.Eve.UnityScene.Tests var secondProjection = lowerer.Lower( PlayableArpgDocument(includeRaider: false, playerPosition: "5,0,2"), Advertisement("aetheria.daemon.game")); - var secondPresentation = presenter.Apply(secondProjection); + var secondPresentation = presenter.Apply(SnapshotWorld(secondProjection.PlayableWorld!)); Assert.That(secondPresentation.UpsertedEntities, Is.EqualTo(2)); Assert.That(secondPresentation.RemovedEntities, Is.EqualTo(1)); @@ -1888,6 +1888,27 @@ namespace GameCult.Eve.UnityScene.Tests Assert.That(sink.Upserts[3].entity.PositionZ, Is.EqualTo(2f)); } + [Test] + public void PlayableWorldSurfaceCannotOverwriteLiveBodyEntities() + { + var projection = new EveUnitySceneSurfaceLowerer() + .Lower(PlayableArpgDocument(), Advertisement("aetheria.daemon.game")); + var sink = new FakePlayableWorldSceneSink(); + var presenter = new EveUnityPlayableWorldPresenter( + sink, + new EveUnityAssetRefResolver(), + liveEntityBodyOwner: true); + + var presentation = presenter.Apply(projection); + + Assert.That(projection.PlayableWorld!.EntityBodyId, Is.Not.Empty); + Assert.That(sink.ConfiguredWorlds.Count, Is.EqualTo(1)); + Assert.That(sink.Upserts, Is.Empty); + Assert.That(sink.RemovedEntityIds, Is.Empty); + Assert.That(presentation.UpsertedEntities, Is.Zero); + Assert.That(presentation.RemovedEntities, Is.Zero); + } + [Test] public void LivePlayableWorldClientPresentsProviderSnapshotsAndKeepsCommandsProviderOwned() { @@ -2950,6 +2971,21 @@ namespace GameCult.Eve.UnityScene.Tests } } + private static EveUnityPlayableWorldProjection SnapshotWorld(EveUnityPlayableWorldProjection source) => + new EveUnityPlayableWorldProjection( + source.WorldRootId, + source.StatePointerId, + source.AssetManifest, + source.InputProfile, + source.CameraRig, + source.ViewId, + source.PlayerEntityId, + source.MovementCommand, + source.FocusCommand, + source.TargetCommand, + source.ActionCommand, + source.Entities); + private static EveUnityPlayableWorldEntity PlayableEntityModel( string entityId, string assetRef, diff --git a/packages/org.gamecult.eve.unity-scene/package.json b/packages/org.gamecult.eve.unity-scene/package.json index c84f62f..5a4e87d 100644 --- a/packages/org.gamecult.eve.unity-scene/package.json +++ b/packages/org.gamecult.eve.unity-scene/package.json @@ -1,7 +1,7 @@ { "name": "org.gamecult.eve.unity-scene", "displayName": "Eve Unity Scene Lowering", - "version": "0.3.103", + "version": "0.3.104", "unity": "6000.0", "description": "Provider-agnostic Unity scene shell for gamecult.eve.surface.v1 interactive world surfaces.", "dependencies": {