From 6ff45d0bbf3b1f2ea70d6a808504139342d432c9 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 15 Jul 2026 22:32:26 +0100 Subject: [PATCH] Pin witness to convergence camera release --- .../PlayMode/GenericWorldCaptureTests.cs | 47 ++++++++++++++++++- ReleaseConsumerProject/Packages/manifest.json | 2 +- .../Packages/packages-lock.json | 4 +- .../PlayMode/GenericWorldCaptureTests.cs | 47 ++++++++++++++++++- docs/aetheria-released-package-witness.md | 36 ++++++++------ scripts/run-aetheria-daemon-world-witness.ps1 | 2 +- 6 files changed, 117 insertions(+), 21 deletions(-) diff --git a/ReleaseConsumerProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs b/ReleaseConsumerProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs index d2dd834..57d685b 100644 --- a/ReleaseConsumerProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs +++ b/ReleaseConsumerProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs @@ -521,7 +521,7 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests "A reconciled fire request never reached daemon-owned lock acquisition and shot resolution."); observedCombat = EveUnityCombatPresentation.Find(runtime.ActiveProjection); Assert.That(observedShot.TargetEntityIndex, Is.EqualTo(targetEntityIndex)); - Assert.That(observedShot.LockQuality, Is.GreaterThan(0.99)); + Assert.That(observedShot.LockQuality, Is.GreaterThanOrEqualTo(0.99)); var trajectories = root.GetComponent(); var combatRenderer = root.GetComponent(); Assert.That(trajectories, Is.Not.Null); @@ -592,6 +592,7 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests Assert.That(aimDotDistance, Is.GreaterThanOrEqualTo(49.9f)); Assert.That(camera.cullingMask & (1 << mapLayer), Is.Zero); Assert.That(runtime.ActiveWorld.CameraRig, Is.EqualTo("perspective.entity-forward-follow.v1")); + Assert.That(runtime.ActiveWorld.CameraLookAt, Is.EqualTo("aim.convergence-point.v1")); Assert.That(runtime.ActiveWorld.CameraDistance, Is.EqualTo(30f).Within(0.001f)); Assert.That(camera.fieldOfView, Is.EqualTo(60f).Within(0.001f)); Assert.That(runtime.ActiveWorld.CameraPositionDamping, Is.EqualTo(0f).Within(0.001f)); @@ -703,6 +704,14 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests "The generic volume lowerer did not rasterize any advertised Fields layers."); Assert.That(fieldVolume.CompositeCount, Is.GreaterThan(0), "The generic volume lowerer never composited into the pilot camera."); + var fieldDocument = typeof(EveUnityFieldsVolumeRenderer) + .GetField("_document", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) + ?.GetValue(fieldVolume); + Assert.That(fieldDocument, Is.Not.Null, "The volume lowerer did not retain its presented Fields document."); + var fieldViewport = fieldDocument.GetType().GetProperty("Viewport")?.GetValue(fieldDocument); + var fieldSplats = fieldDocument.GetType().GetProperty("Splats")?.GetValue(fieldDocument); + Assert.That(fieldViewport, Is.Not.Null); + Assert.That(fieldSplats, Is.Not.Null); WriteWitnessFacts( initialVersion, runtime.ActiveVersion, @@ -744,6 +753,15 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests finalPickupEntityCount, pickupCollectionEventCount, pickupCollection, + camera.transform.position, + camera.transform.forward, + playerMarker.transform.position, + aimRenderer.ViewDotPosition, + Convert.ToSingle(fieldViewport.GetType().GetProperty("MinX")?.GetValue(fieldViewport)), + Convert.ToSingle(fieldViewport.GetType().GetProperty("MinY")?.GetValue(fieldViewport)), + Convert.ToSingle(fieldViewport.GetType().GetProperty("MaxX")?.GetValue(fieldViewport)), + Convert.ToSingle(fieldViewport.GetType().GetProperty("MaxY")?.GetValue(fieldViewport)), + Convert.ToInt32(fieldSplats.GetType().GetProperty("Count")?.GetValue(fieldSplats)), playerRendererFacts); } finally @@ -803,6 +821,15 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests int finalPickupEntityCount, int pickupCollectionEventCount, EveUnityFeedbackEvent pickupCollection, + Vector3 cameraPosition, + Vector3 cameraForward, + Vector3 playerPosition, + Vector3 aimPosition, + float fieldViewportMinX, + float fieldViewportMinY, + float fieldViewportMaxX, + float fieldViewportMaxY, + int fieldSplatCount, RendererFact[] playerRendererFacts) { var path = Environment.GetEnvironmentVariable("EVEUNITY_WITNESS_FACTS_PATH"); @@ -857,6 +884,15 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests pickupQuantity = (float)(pickupCollection?.ScalarValue ?? 0), cargoQuantityBeforePickup = (float)(pickupCollection?.CargoQuantityBefore ?? 0), cargoQuantityAfterPickup = (float)(pickupCollection?.CargoQuantityAfter ?? 0), + cameraPosition = cameraPosition, + cameraForward = cameraForward, + playerPosition = playerPosition, + aimPosition = aimPosition, + fieldViewportMinX = fieldViewportMinX, + fieldViewportMinY = fieldViewportMinY, + fieldViewportMaxX = fieldViewportMaxX, + fieldViewportMaxY = fieldViewportMaxY, + fieldSplatCount = fieldSplatCount, playerRenderers = playerRendererFacts, mapChannelRendererCount = mapChannelRendererCount, mapChangedPixels = mapChangedPixels, @@ -918,6 +954,15 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests public float pickupQuantity; public float cargoQuantityBeforePickup; public float cargoQuantityAfterPickup; + public Vector3 cameraPosition; + public Vector3 cameraForward; + public Vector3 playerPosition; + public Vector3 aimPosition; + public float fieldViewportMinX; + public float fieldViewportMinY; + public float fieldViewportMaxX; + public float fieldViewportMaxY; + public int fieldSplatCount; public RendererFact[] playerRenderers; public int mapChannelRendererCount; public int mapChangedPixels; diff --git a/ReleaseConsumerProject/Packages/manifest.json b/ReleaseConsumerProject/Packages/manifest.json index bfb6fa3..cdfcff1 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.13", "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.0", "org.gamecult.eve.surface": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.surface#eveunity-surface-v0.2.2", - "org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.40", + "org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.41", "org.gamecult.eve.unity-uitoolkit": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-uitoolkit#eveunity-uitoolkit-v0.1.1" }, "testables": [ diff --git a/ReleaseConsumerProject/Packages/packages-lock.json b/ReleaseConsumerProject/Packages/packages-lock.json index dd2dc39..cdae045 100644 --- a/ReleaseConsumerProject/Packages/packages-lock.json +++ b/ReleaseConsumerProject/Packages/packages-lock.json @@ -144,7 +144,7 @@ "hash": "140e1bd963a0033e66777a3b2c5fe6e9c97dfe32" }, "org.gamecult.eve.unity-scene": { - "version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.40", + "version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.41", "depth": 0, "source": "git", "dependencies": { @@ -154,7 +154,7 @@ "com.unity.mathematics": "1.3.2", "com.unity.modules.particlesystem": "1.0.0" }, - "hash": "3c8d127ef8d0d8e6c9a45f92a8bbd553d87e6a07" + "hash": "f0883e9644674849e03127d4d7a231905092f1de" }, "org.gamecult.eve.unity-uitoolkit": { "version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-uitoolkit#eveunity-uitoolkit-v0.1.1", diff --git a/TestProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs b/TestProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs index d2dd834..57d685b 100644 --- a/TestProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs +++ b/TestProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs @@ -521,7 +521,7 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests "A reconciled fire request never reached daemon-owned lock acquisition and shot resolution."); observedCombat = EveUnityCombatPresentation.Find(runtime.ActiveProjection); Assert.That(observedShot.TargetEntityIndex, Is.EqualTo(targetEntityIndex)); - Assert.That(observedShot.LockQuality, Is.GreaterThan(0.99)); + Assert.That(observedShot.LockQuality, Is.GreaterThanOrEqualTo(0.99)); var trajectories = root.GetComponent(); var combatRenderer = root.GetComponent(); Assert.That(trajectories, Is.Not.Null); @@ -592,6 +592,7 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests Assert.That(aimDotDistance, Is.GreaterThanOrEqualTo(49.9f)); Assert.That(camera.cullingMask & (1 << mapLayer), Is.Zero); Assert.That(runtime.ActiveWorld.CameraRig, Is.EqualTo("perspective.entity-forward-follow.v1")); + Assert.That(runtime.ActiveWorld.CameraLookAt, Is.EqualTo("aim.convergence-point.v1")); Assert.That(runtime.ActiveWorld.CameraDistance, Is.EqualTo(30f).Within(0.001f)); Assert.That(camera.fieldOfView, Is.EqualTo(60f).Within(0.001f)); Assert.That(runtime.ActiveWorld.CameraPositionDamping, Is.EqualTo(0f).Within(0.001f)); @@ -703,6 +704,14 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests "The generic volume lowerer did not rasterize any advertised Fields layers."); Assert.That(fieldVolume.CompositeCount, Is.GreaterThan(0), "The generic volume lowerer never composited into the pilot camera."); + var fieldDocument = typeof(EveUnityFieldsVolumeRenderer) + .GetField("_document", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) + ?.GetValue(fieldVolume); + Assert.That(fieldDocument, Is.Not.Null, "The volume lowerer did not retain its presented Fields document."); + var fieldViewport = fieldDocument.GetType().GetProperty("Viewport")?.GetValue(fieldDocument); + var fieldSplats = fieldDocument.GetType().GetProperty("Splats")?.GetValue(fieldDocument); + Assert.That(fieldViewport, Is.Not.Null); + Assert.That(fieldSplats, Is.Not.Null); WriteWitnessFacts( initialVersion, runtime.ActiveVersion, @@ -744,6 +753,15 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests finalPickupEntityCount, pickupCollectionEventCount, pickupCollection, + camera.transform.position, + camera.transform.forward, + playerMarker.transform.position, + aimRenderer.ViewDotPosition, + Convert.ToSingle(fieldViewport.GetType().GetProperty("MinX")?.GetValue(fieldViewport)), + Convert.ToSingle(fieldViewport.GetType().GetProperty("MinY")?.GetValue(fieldViewport)), + Convert.ToSingle(fieldViewport.GetType().GetProperty("MaxX")?.GetValue(fieldViewport)), + Convert.ToSingle(fieldViewport.GetType().GetProperty("MaxY")?.GetValue(fieldViewport)), + Convert.ToInt32(fieldSplats.GetType().GetProperty("Count")?.GetValue(fieldSplats)), playerRendererFacts); } finally @@ -803,6 +821,15 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests int finalPickupEntityCount, int pickupCollectionEventCount, EveUnityFeedbackEvent pickupCollection, + Vector3 cameraPosition, + Vector3 cameraForward, + Vector3 playerPosition, + Vector3 aimPosition, + float fieldViewportMinX, + float fieldViewportMinY, + float fieldViewportMaxX, + float fieldViewportMaxY, + int fieldSplatCount, RendererFact[] playerRendererFacts) { var path = Environment.GetEnvironmentVariable("EVEUNITY_WITNESS_FACTS_PATH"); @@ -857,6 +884,15 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests pickupQuantity = (float)(pickupCollection?.ScalarValue ?? 0), cargoQuantityBeforePickup = (float)(pickupCollection?.CargoQuantityBefore ?? 0), cargoQuantityAfterPickup = (float)(pickupCollection?.CargoQuantityAfter ?? 0), + cameraPosition = cameraPosition, + cameraForward = cameraForward, + playerPosition = playerPosition, + aimPosition = aimPosition, + fieldViewportMinX = fieldViewportMinX, + fieldViewportMinY = fieldViewportMinY, + fieldViewportMaxX = fieldViewportMaxX, + fieldViewportMaxY = fieldViewportMaxY, + fieldSplatCount = fieldSplatCount, playerRenderers = playerRendererFacts, mapChannelRendererCount = mapChannelRendererCount, mapChangedPixels = mapChangedPixels, @@ -918,6 +954,15 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests public float pickupQuantity; public float cargoQuantityBeforePickup; public float cargoQuantityAfterPickup; + public Vector3 cameraPosition; + public Vector3 cameraForward; + public Vector3 playerPosition; + public Vector3 aimPosition; + public float fieldViewportMinX; + public float fieldViewportMinY; + public float fieldViewportMaxX; + public float fieldViewportMaxY; + public int fieldSplatCount; public RendererFact[] playerRenderers; public int mapChannelRendererCount; public int mapChangedPixels; diff --git a/docs/aetheria-released-package-witness.md b/docs/aetheria-released-package-witness.md index aa1b984..d0f3761 100644 --- a/docs/aetheria-released-package-witness.md +++ b/docs/aetheria-released-package-witness.md @@ -4,8 +4,8 @@ The warm-cache released-package witness passes with: -- `org.gamecult.eve.unity-scene` `0.3.40`, commit - `3c8d127ef8d0d8e6c9a45f92a8bbd553d87e6a07`; +- `org.gamecult.eve.unity-scene` `0.3.41`, commit + `f0883e9644674849e03127d4d7a231905092f1de`; - `org.gamecult.eve.plugin-fields` `0.2.0`, commit `382a23d8f8a07e4b5eef5f81f84655861a858367`; - `org.gamecult.eve.surface` `0.2.2`, commit @@ -17,7 +17,7 @@ The warm-cache released-package witness passes with: - the generic `ReleaseConsumerProject` client connected directly to the Aetheria daemon. -Evidence is in `artifacts/aetheria-daemon-gravity-fog-dither`. The PlayMode test +Evidence is in `artifacts/aetheria-daemon-gravity-fog-convergence-facts`. The PlayMode test passed and recorded provider-owned reconciled movement, look, targeting, tractor press, tractor release, contact-gated cargo collection, and action receipts. The daemon-owned look direction reached the SoA body rotation, @@ -31,7 +31,9 @@ the only live directional light (`0.75` intensity). Aetheria also advertises the original undocked `ARPG.unity` Third Person Rig: entity-forward perspective follow, `30` unit distance, `60` degree vertical field of view, target screen position `0.64,0.81`, zero position damping, and -`1`-`4096` clip planes. The generic camera rig lowers those values without +`1`-`4096` clip planes. Its generic `aim.convergence-point.v1` relation makes +the optical axis reach the daemon-published aim point while preserving that +entity framing. The generic camera rig lowers both constraints without Aetheria-specific camera code. The distinct `70` unit Docked Rig no longer incorrectly owns the flight view. Aetheria's pilot surface also publishes a transparent cockpit overlay. The @@ -48,7 +50,7 @@ Fields splat layers. Its surface contract contains logical ports such as names or pass indices. The selected `unity-scene` provider asset variant owns that concrete shader ABI through `unity.volume.*` metadata. The released generic lowerer resolved the provider shader and dither texture, rasterized all -four layers, and composited `22` pilot-camera frames from daemon frame `232`. +four layers, and composited `21` pilot-camera frames from daemon frame `220`. The provider variant advertises the fossil shader's raymarch, temporal-history, and composite passes plus their logical ports. EveUnity allocates and resets the history targets generically; a partial temporal ABI fails closed. @@ -63,10 +65,10 @@ Camera-channel facts: - provider-authored player renderers: `13`, including the lowered tractor effect; - pilot changed pixels: `230,400`; -- pilot average luminance: `0.1893132`; -- pilot bright pixels: `13,948`; +- pilot average luminance: `0.1912306`; +- pilot bright pixels: `13,715`; - map-channel renderers: `11`; -- map changed pixels: `4,365`; +- map changed pixels: `4,867`; - native cockpit progress bars: `7`; - daemon tractor power at capture: `1.0` after the held input completed its authored ramp; @@ -85,14 +87,18 @@ Visual inspection confirms that map glyphs are absent from the pilot frame and present in the map-only frame. Correcting the fossil camera mode removed the false top-down dark disk, but the active volume now resolves as a nearly uniform saturated orange horizon rather than the fossil's blue gravity-shaped fog sea. -This is transport and lowering proof, not visual parity. Release `0.3.40` now +This is transport and lowering proof, not visual parity. Release `0.3.41` now derives dither sampling coordinates from the active viewport and provider -texture dimensions through a generic logical-port relation. The resulting -raymarch remains nearly flat orange (`R 0.8896-0.8960`, `G 0.5493-0.5532`, -`B 0.3096-0.3118`, alpha `0`), so that real ABI correction is not the missing -visual mechanism. The next diagnosis must compare camera/world sampling and -field viewport placement before changing authored tuning. EveUnity must not -compensate with Aetheria-specific lighting or fog rules. +texture dimensions through a generic logical-port relation and solves the +advertised finite aim look-at exactly. The camera (`6.57,-13.83,1.44`), player +(`-3.20,0,38.77`), and aim (`-46.55,0,119.19`) all lie inside the advertised +field viewport, but the resulting raymarch remains nearly flat orange +(`R 0.8896-0.8960`, `G 0.5493-0.5532`, `B 0.3096-0.3118`, alpha `0`). The +remaining cause is now isolated to the daemon's field document: it flattened +the fossil radial gravity terrain into a full-viewport solid height splat, so +the first ray sample saturates floor density. EveUnity must not compensate with +Aetheria-specific lighting or fog rules; the document must publish the actual +portable radial falloff. Substance is not part of this path; later texture baking belongs in Blender. Aetheria currently bundles ambientCG's 1K `Metal012` color, normal, and metalness maps under CC0. The same pre-generated maps now replace dead diff --git a/scripts/run-aetheria-daemon-world-witness.ps1 b/scripts/run-aetheria-daemon-world-witness.ps1 index 3350577..9202306 100644 --- a/scripts/run-aetheria-daemon-world-witness.ps1 +++ b/scripts/run-aetheria-daemon-world-witness.ps1 @@ -13,7 +13,7 @@ param( ) $ErrorActionPreference = "Stop" -$expectedEveUnityCommit = "3c8d127ef8d0d8e6c9a45f92a8bbd553d87e6a07" +$expectedEveUnityCommit = "f0883e9644674849e03127d4d7a231905092f1de" $expectedEveFieldsCommit = "382a23d8f8a07e4b5eef5f81f84655861a858367" $expectedEveUnityUiToolkitCommit = "4d0cbe0185bdc4fc65eb63503a7c5cb578539669" $expectedCultLibCommit = "feb5c71513e71d681699f462fe3682b3168c6f73"