Prove released provider volume lowering
This commit is contained in:
parent
5ce6548007
commit
4a513f4264
8 changed files with 299 additions and 35 deletions
|
|
@ -461,6 +461,31 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
Assert.That(finalPickupEntityCount, Is.EqualTo(initialPickupEntityCount - 1),
|
||||
"Collected pickup remained in the provider-authored entity generation.");
|
||||
|
||||
targetFact = host.PresentedEntities.CurrentGeneration.Entities
|
||||
.Single(entity => entity.EntityId == targetEntityId);
|
||||
playerFact = host.PresentedEntities.CurrentGeneration.Entities
|
||||
.Single(entity => entity.EntityId == playerId);
|
||||
aim = targetFact.Position - playerFact.Position;
|
||||
aim.y = 0;
|
||||
Assert.That(aim.sqrMagnitude, Is.GreaterThan(0.0001f));
|
||||
aim.Normalize();
|
||||
lookVersion = runtime.ActiveVersion;
|
||||
look = runtime.SubmitLookDirectionIntent(playerId, aim.x, 0f, aim.z);
|
||||
lookDeadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < lookDeadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != look.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase) ||
|
||||
runtime.ActiveVersion < runtime.LastReceipt.SourceVersion ||
|
||||
Vector3.Dot(FindMarker(root, playerId).transform.forward, aim) < 0.99f))
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
}
|
||||
AssertReconciledProviderReceipt(runtime.LastReceipt, look.CommandId,
|
||||
provider.Selection.ProviderId, provider.Selection.SurfaceId, lookVersion);
|
||||
Assert.That(Vector3.Dot(FindMarker(root, playerId).transform.forward, aim), Is.GreaterThan(0.99f));
|
||||
lookReceipt = WitnessReceipt.From("look", runtime.LastReceipt);
|
||||
|
||||
var focusVersion = runtime.ActiveVersion;
|
||||
var inputDriver = root.GetComponent<EveUnityPlayableWorldInputDriver>() ??
|
||||
root.AddComponent<EveUnityPlayableWorldInputDriver>();
|
||||
|
|
@ -605,6 +630,8 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(capturePath)));
|
||||
File.WriteAllBytes(capturePath, pixels.EncodeToPNG());
|
||||
Assert.That(new FileInfo(capturePath).Length, Is.GreaterThan(1024));
|
||||
WriteFieldLayerCaptures(root, host.Runtime.ActiveWorld, capturePath);
|
||||
WriteFieldCloudCapture(root, capturePath);
|
||||
MeasureRendererOutputs(
|
||||
camera,
|
||||
target,
|
||||
|
|
@ -1098,6 +1125,11 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
renderer.enabled = false;
|
||||
camera.clearFlags = CameraClearFlags.SolidColor;
|
||||
camera.backgroundColor = Color.black;
|
||||
camera.Render();
|
||||
RenderTexture.active = target;
|
||||
pixels.ReadPixels(new Rect(0, 0, target.width, target.height), 0, 0);
|
||||
pixels.Apply();
|
||||
var baseline = pixels.GetPixels();
|
||||
for (var index = 0; index < measuredRenderers.Count; index++)
|
||||
{
|
||||
var fact = facts[index];
|
||||
|
|
@ -1106,9 +1138,10 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
RenderTexture.active = target;
|
||||
pixels.ReadPixels(new Rect(0, 0, target.width, target.height), 0, 0);
|
||||
pixels.Apply();
|
||||
fact.renderedPixelCount = CountChangedPixels(pixels, Color.black);
|
||||
MeasureLuminance(
|
||||
pixels,
|
||||
MeasureDifference(
|
||||
pixels.GetPixels(),
|
||||
baseline,
|
||||
out fact.renderedPixelCount,
|
||||
out fact.renderedAverageLuminance,
|
||||
out fact.renderedBrightPixelCount);
|
||||
measuredRenderers[index].enabled = false;
|
||||
|
|
@ -1123,6 +1156,32 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
}
|
||||
}
|
||||
|
||||
private static void MeasureDifference(
|
||||
IReadOnlyList<Color> actual,
|
||||
IReadOnlyList<Color> baseline,
|
||||
out int changedPixelCount,
|
||||
out float averageLuminance,
|
||||
out int brightPixelCount)
|
||||
{
|
||||
changedPixelCount = 0;
|
||||
brightPixelCount = 0;
|
||||
double total = 0;
|
||||
var count = Math.Min(actual.Count, baseline.Count);
|
||||
for (var index = 0; index < count; index++)
|
||||
{
|
||||
var delta = new Color(
|
||||
Mathf.Abs(actual[index].r - baseline[index].r),
|
||||
Mathf.Abs(actual[index].g - baseline[index].g),
|
||||
Mathf.Abs(actual[index].b - baseline[index].b));
|
||||
var magnitude = delta.r + delta.g + delta.b;
|
||||
if (magnitude > 0.08f) changedPixelCount++;
|
||||
var luminance = delta.r * 0.2126f + delta.g * 0.7152f + delta.b * 0.0722f;
|
||||
total += luminance;
|
||||
if (luminance >= 0.2f) brightPixelCount++;
|
||||
}
|
||||
averageLuminance = count == 0 ? 0f : (float)(total / count);
|
||||
}
|
||||
|
||||
private static int CountChangedPixels(Texture2D texture, Color background)
|
||||
{
|
||||
var changed = 0;
|
||||
|
|
@ -1136,6 +1195,59 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
return changed;
|
||||
}
|
||||
|
||||
private static void WriteFieldLayerCaptures(GameObject root, EveUnityPlayableWorldProjection world, string capturePath)
|
||||
{
|
||||
var renderer = root.GetComponent<EveFieldsSplatLayerRenderer>();
|
||||
if (renderer == null || world == null || string.IsNullOrWhiteSpace(capturePath)) return;
|
||||
var directory = Path.GetDirectoryName(Path.GetFullPath(capturePath));
|
||||
foreach (var field in world.FieldVolumes)
|
||||
{
|
||||
if (!field.Props.TryGetValue("layerBindings", out var bindings)) continue;
|
||||
foreach (var pair in (bindings ?? "").Split(';'))
|
||||
{
|
||||
var separator = pair.IndexOf('=');
|
||||
if (separator <= 0) continue;
|
||||
var layerKey = pair.Substring(0, separator).Trim();
|
||||
if (!renderer.TryGetTexture(layerKey, out var texture) || texture == null) continue;
|
||||
var previous = RenderTexture.active;
|
||||
RenderTexture.active = texture;
|
||||
var copy = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false, true);
|
||||
copy.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0);
|
||||
copy.Apply();
|
||||
RenderTexture.active = previous;
|
||||
File.WriteAllBytes(Path.Combine(directory, $"field-{layerKey}.png"), copy.EncodeToPNG());
|
||||
UnityEngine.Object.DestroyImmediate(copy);
|
||||
|
||||
RenderTexture.active = texture;
|
||||
var floatCopy = new Texture2D(texture.width, texture.height, TextureFormat.RGBAFloat, false, true);
|
||||
floatCopy.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0);
|
||||
floatCopy.Apply();
|
||||
RenderTexture.active = previous;
|
||||
File.WriteAllBytes(Path.Combine(directory, $"field-{layerKey}.exr"), floatCopy.EncodeToEXR());
|
||||
UnityEngine.Object.DestroyImmediate(floatCopy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteFieldCloudCapture(GameObject root, string capturePath)
|
||||
{
|
||||
var renderer = root.GetComponent<EveUnityFieldsVolumeRenderer>();
|
||||
var field = typeof(EveUnityFieldsVolumeRenderer).GetField(
|
||||
"_cloudTexture",
|
||||
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
|
||||
var texture = field?.GetValue(renderer) as RenderTexture;
|
||||
if (texture == null || string.IsNullOrWhiteSpace(capturePath)) return;
|
||||
var previous = RenderTexture.active;
|
||||
RenderTexture.active = texture;
|
||||
var copy = new Texture2D(texture.width, texture.height, TextureFormat.RGBAFloat, false, true);
|
||||
copy.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0);
|
||||
copy.Apply();
|
||||
RenderTexture.active = previous;
|
||||
var directory = Path.GetDirectoryName(Path.GetFullPath(capturePath));
|
||||
File.WriteAllBytes(Path.Combine(directory, "field-volume-cloud.exr"), copy.EncodeToEXR());
|
||||
UnityEngine.Object.DestroyImmediate(copy);
|
||||
}
|
||||
|
||||
private static EveUnitySceneProviderSurfaceDocument WorldDocument()
|
||||
{
|
||||
var entities = new[]
|
||||
|
|
|
|||
|
|
@ -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.33",
|
||||
"org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.37",
|
||||
"org.gamecult.eve.unity-uitoolkit": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-uitoolkit#eveunity-uitoolkit-v0.1.1"
|
||||
},
|
||||
"testables": [
|
||||
|
|
|
|||
|
|
@ -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.33",
|
||||
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.37",
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {
|
||||
|
|
@ -154,7 +154,7 @@
|
|||
"com.unity.mathematics": "1.3.2",
|
||||
"com.unity.modules.particlesystem": "1.0.0"
|
||||
},
|
||||
"hash": "852458dade1ae535d2ff3cfc9f8fe430e341ce2a"
|
||||
"hash": "5ce654800760203154132d4b0fd1475294283ba6"
|
||||
},
|
||||
"org.gamecult.eve.unity-uitoolkit": {
|
||||
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-uitoolkit#eveunity-uitoolkit-v0.1.1",
|
||||
|
|
|
|||
|
|
@ -461,6 +461,31 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
Assert.That(finalPickupEntityCount, Is.EqualTo(initialPickupEntityCount - 1),
|
||||
"Collected pickup remained in the provider-authored entity generation.");
|
||||
|
||||
targetFact = host.PresentedEntities.CurrentGeneration.Entities
|
||||
.Single(entity => entity.EntityId == targetEntityId);
|
||||
playerFact = host.PresentedEntities.CurrentGeneration.Entities
|
||||
.Single(entity => entity.EntityId == playerId);
|
||||
aim = targetFact.Position - playerFact.Position;
|
||||
aim.y = 0;
|
||||
Assert.That(aim.sqrMagnitude, Is.GreaterThan(0.0001f));
|
||||
aim.Normalize();
|
||||
lookVersion = runtime.ActiveVersion;
|
||||
look = runtime.SubmitLookDirectionIntent(playerId, aim.x, 0f, aim.z);
|
||||
lookDeadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < lookDeadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != look.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase) ||
|
||||
runtime.ActiveVersion < runtime.LastReceipt.SourceVersion ||
|
||||
Vector3.Dot(FindMarker(root, playerId).transform.forward, aim) < 0.99f))
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
}
|
||||
AssertReconciledProviderReceipt(runtime.LastReceipt, look.CommandId,
|
||||
provider.Selection.ProviderId, provider.Selection.SurfaceId, lookVersion);
|
||||
Assert.That(Vector3.Dot(FindMarker(root, playerId).transform.forward, aim), Is.GreaterThan(0.99f));
|
||||
lookReceipt = WitnessReceipt.From("look", runtime.LastReceipt);
|
||||
|
||||
var focusVersion = runtime.ActiveVersion;
|
||||
var inputDriver = root.GetComponent<EveUnityPlayableWorldInputDriver>() ??
|
||||
root.AddComponent<EveUnityPlayableWorldInputDriver>();
|
||||
|
|
@ -605,6 +630,8 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(capturePath)));
|
||||
File.WriteAllBytes(capturePath, pixels.EncodeToPNG());
|
||||
Assert.That(new FileInfo(capturePath).Length, Is.GreaterThan(1024));
|
||||
WriteFieldLayerCaptures(root, host.Runtime.ActiveWorld, capturePath);
|
||||
WriteFieldCloudCapture(root, capturePath);
|
||||
MeasureRendererOutputs(
|
||||
camera,
|
||||
target,
|
||||
|
|
@ -1098,6 +1125,11 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
renderer.enabled = false;
|
||||
camera.clearFlags = CameraClearFlags.SolidColor;
|
||||
camera.backgroundColor = Color.black;
|
||||
camera.Render();
|
||||
RenderTexture.active = target;
|
||||
pixels.ReadPixels(new Rect(0, 0, target.width, target.height), 0, 0);
|
||||
pixels.Apply();
|
||||
var baseline = pixels.GetPixels();
|
||||
for (var index = 0; index < measuredRenderers.Count; index++)
|
||||
{
|
||||
var fact = facts[index];
|
||||
|
|
@ -1106,9 +1138,10 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
RenderTexture.active = target;
|
||||
pixels.ReadPixels(new Rect(0, 0, target.width, target.height), 0, 0);
|
||||
pixels.Apply();
|
||||
fact.renderedPixelCount = CountChangedPixels(pixels, Color.black);
|
||||
MeasureLuminance(
|
||||
pixels,
|
||||
MeasureDifference(
|
||||
pixels.GetPixels(),
|
||||
baseline,
|
||||
out fact.renderedPixelCount,
|
||||
out fact.renderedAverageLuminance,
|
||||
out fact.renderedBrightPixelCount);
|
||||
measuredRenderers[index].enabled = false;
|
||||
|
|
@ -1123,6 +1156,32 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
}
|
||||
}
|
||||
|
||||
private static void MeasureDifference(
|
||||
IReadOnlyList<Color> actual,
|
||||
IReadOnlyList<Color> baseline,
|
||||
out int changedPixelCount,
|
||||
out float averageLuminance,
|
||||
out int brightPixelCount)
|
||||
{
|
||||
changedPixelCount = 0;
|
||||
brightPixelCount = 0;
|
||||
double total = 0;
|
||||
var count = Math.Min(actual.Count, baseline.Count);
|
||||
for (var index = 0; index < count; index++)
|
||||
{
|
||||
var delta = new Color(
|
||||
Mathf.Abs(actual[index].r - baseline[index].r),
|
||||
Mathf.Abs(actual[index].g - baseline[index].g),
|
||||
Mathf.Abs(actual[index].b - baseline[index].b));
|
||||
var magnitude = delta.r + delta.g + delta.b;
|
||||
if (magnitude > 0.08f) changedPixelCount++;
|
||||
var luminance = delta.r * 0.2126f + delta.g * 0.7152f + delta.b * 0.0722f;
|
||||
total += luminance;
|
||||
if (luminance >= 0.2f) brightPixelCount++;
|
||||
}
|
||||
averageLuminance = count == 0 ? 0f : (float)(total / count);
|
||||
}
|
||||
|
||||
private static int CountChangedPixels(Texture2D texture, Color background)
|
||||
{
|
||||
var changed = 0;
|
||||
|
|
@ -1136,6 +1195,59 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
return changed;
|
||||
}
|
||||
|
||||
private static void WriteFieldLayerCaptures(GameObject root, EveUnityPlayableWorldProjection world, string capturePath)
|
||||
{
|
||||
var renderer = root.GetComponent<EveFieldsSplatLayerRenderer>();
|
||||
if (renderer == null || world == null || string.IsNullOrWhiteSpace(capturePath)) return;
|
||||
var directory = Path.GetDirectoryName(Path.GetFullPath(capturePath));
|
||||
foreach (var field in world.FieldVolumes)
|
||||
{
|
||||
if (!field.Props.TryGetValue("layerBindings", out var bindings)) continue;
|
||||
foreach (var pair in (bindings ?? "").Split(';'))
|
||||
{
|
||||
var separator = pair.IndexOf('=');
|
||||
if (separator <= 0) continue;
|
||||
var layerKey = pair.Substring(0, separator).Trim();
|
||||
if (!renderer.TryGetTexture(layerKey, out var texture) || texture == null) continue;
|
||||
var previous = RenderTexture.active;
|
||||
RenderTexture.active = texture;
|
||||
var copy = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false, true);
|
||||
copy.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0);
|
||||
copy.Apply();
|
||||
RenderTexture.active = previous;
|
||||
File.WriteAllBytes(Path.Combine(directory, $"field-{layerKey}.png"), copy.EncodeToPNG());
|
||||
UnityEngine.Object.DestroyImmediate(copy);
|
||||
|
||||
RenderTexture.active = texture;
|
||||
var floatCopy = new Texture2D(texture.width, texture.height, TextureFormat.RGBAFloat, false, true);
|
||||
floatCopy.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0);
|
||||
floatCopy.Apply();
|
||||
RenderTexture.active = previous;
|
||||
File.WriteAllBytes(Path.Combine(directory, $"field-{layerKey}.exr"), floatCopy.EncodeToEXR());
|
||||
UnityEngine.Object.DestroyImmediate(floatCopy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteFieldCloudCapture(GameObject root, string capturePath)
|
||||
{
|
||||
var renderer = root.GetComponent<EveUnityFieldsVolumeRenderer>();
|
||||
var field = typeof(EveUnityFieldsVolumeRenderer).GetField(
|
||||
"_cloudTexture",
|
||||
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
|
||||
var texture = field?.GetValue(renderer) as RenderTexture;
|
||||
if (texture == null || string.IsNullOrWhiteSpace(capturePath)) return;
|
||||
var previous = RenderTexture.active;
|
||||
RenderTexture.active = texture;
|
||||
var copy = new Texture2D(texture.width, texture.height, TextureFormat.RGBAFloat, false, true);
|
||||
copy.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0);
|
||||
copy.Apply();
|
||||
RenderTexture.active = previous;
|
||||
var directory = Path.GetDirectoryName(Path.GetFullPath(capturePath));
|
||||
File.WriteAllBytes(Path.Combine(directory, "field-volume-cloud.exr"), copy.EncodeToEXR());
|
||||
UnityEngine.Object.DestroyImmediate(copy);
|
||||
}
|
||||
|
||||
private static EveUnitySceneProviderSurfaceDocument WorldDocument()
|
||||
{
|
||||
var entities = new[]
|
||||
|
|
|
|||
|
|
@ -33,7 +33,9 @@
|
|||
"version": "file:../../../EvePlugins/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields",
|
||||
"depth": 0,
|
||||
"source": "local",
|
||||
"dependencies": {}
|
||||
"dependencies": {
|
||||
"org.gamecult.cultlib": "1.0.13"
|
||||
}
|
||||
},
|
||||
"org.gamecult.eve.surface": {
|
||||
"version": "file:../../packages/org.gamecult.eve.surface",
|
||||
|
|
@ -49,7 +51,7 @@
|
|||
"source": "local",
|
||||
"dependencies": {
|
||||
"org.gamecult.cultlib": "1.0.13",
|
||||
"org.gamecult.eve.plugin-fields": "0.1.1",
|
||||
"org.gamecult.eve.plugin-fields": "0.2.0",
|
||||
"org.gamecult.eve.surface": "0.2.2",
|
||||
"com.unity.mathematics": "1.3.2",
|
||||
"com.unity.modules.particlesystem": "1.0.0"
|
||||
|
|
|
|||
|
|
@ -4,9 +4,12 @@
|
|||
|
||||
The warm-cache released-package witness passes with:
|
||||
|
||||
- `org.gamecult.eve.unity-scene` `0.3.32`, commit
|
||||
`817912a041ac1911e1e27a4b88617754d90ad4b7`;
|
||||
- `org.gamecult.eve.surface` `0.2.2`, from the same commit;
|
||||
- `org.gamecult.eve.unity-scene` `0.3.37`, commit
|
||||
`5ce654800760203154132d4b0fd1475294283ba6`;
|
||||
- `org.gamecult.eve.plugin-fields` `0.2.0`, commit
|
||||
`382a23d8f8a07e4b5eef5f81f84655861a858367`;
|
||||
- `org.gamecult.eve.surface` `0.2.2`, commit
|
||||
`140e1bd963a0033e66777a3b2c5fe6e9c97dfe32`;
|
||||
- `org.gamecult.eve.unity-uitoolkit` `0.1.1`, commit
|
||||
`4d0cbe0185bdc4fc65eb63503a7c5cb578539669`;
|
||||
- `org.gamecult.cultlib` `1.0.13`, commit
|
||||
|
|
@ -14,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-native-0326-warm`. The PlayMode test
|
||||
Evidence is in `artifacts/aetheria-daemon-gravity-fog-warm`. 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,
|
||||
|
|
@ -37,6 +40,14 @@ with `display: none` in the pilot presentation. The runnable generic-client
|
|||
launcher mounts the same advertised document and forwards its typed commands;
|
||||
it contains no Aetheria gameplay or client-authored world light.
|
||||
|
||||
The same surface publishes a `field.volume3d` node over four canonical Eve
|
||||
Fields splat layers. Its surface contract contains logical ports such as
|
||||
`surfaceHeight`, `patch`, and `tint`; it contains no Unity `_Nebula*` property
|
||||
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 `220`.
|
||||
|
||||
The two PNGs below are deliberate camera-channel captures, not a composited
|
||||
screen capture, so they prove world/map isolation rather than HUD pixels. The
|
||||
native cockpit proof is the asserted UI Toolkit visual tree recorded as
|
||||
|
|
@ -46,11 +57,11 @@ daemon lock progress `1.0`; Unity does not manufacture or smooth that value.
|
|||
Camera-channel facts:
|
||||
|
||||
- provider-authored player renderers: `13`, including the lowered tractor effect;
|
||||
- pilot changed pixels: `230,302`;
|
||||
- pilot average luminance: `0.002843`;
|
||||
- pilot bright pixels: `1,040`;
|
||||
- pilot changed pixels: `230,323`;
|
||||
- pilot average luminance: `0.0532403`;
|
||||
- pilot bright pixels: `954`;
|
||||
- map-channel renderers: `11`;
|
||||
- map changed pixels: `3,921`;
|
||||
- map changed pixels: `4,115`;
|
||||
- native cockpit progress bars: `7`;
|
||||
- daemon tractor power at capture: `1.0` after the held input completed its
|
||||
authored ramp;
|
||||
|
|
@ -66,12 +77,12 @@ Camera-channel facts:
|
|||
- the map camera renders exactly the advertised map layer.
|
||||
|
||||
Visual inspection confirms that map glyphs are absent from the pilot frame and
|
||||
present in the map-only frame. Restoring the authored ARPG camera in place of
|
||||
the copied TestScene tuning increased hull-renderer pixel coverage by roughly
|
||||
four times and bright pilot pixels from `502` to `1,319`. The pilot presentation
|
||||
remains dark. Renderer-isolation facts prove that the hull draws under the
|
||||
provider-owned light, so the next native-art work is available pre-generated
|
||||
provider textures, not a client-side lighting fallback.
|
||||
present in the map-only frame. The pilot frame also shows the provider-owned
|
||||
gravity-shaped fog basin rather than a client-authored background effect. Its
|
||||
current dark, broad shape is transport/lowering proof, not visual-parity proof;
|
||||
restoring the fossil's cloud structure, scale, tint range, and scene readability
|
||||
remains provider art work. EveUnity must not compensate with Aetheria-specific
|
||||
lighting or fog rules.
|
||||
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
|
||||
|
|
@ -112,8 +123,8 @@ Primary artifacts:
|
|||
|
||||
## Cold delivery is not currently proven
|
||||
|
||||
The current `46,131,569` byte Unity bundle (SHA-256
|
||||
`a4b26fb234ae7d82eda26fb342d7f77a236e3bc1107420175eb1c626785db212`)
|
||||
The current `46,413,003` byte Unity bundle (SHA-256
|
||||
`229a7833120d9b4fe7e4270f13adc8ce8e553246a99efcbf20bb50d3ca18494d`)
|
||||
times out from an empty cache. Its bytes are
|
||||
still transported through batched snapshot records rather than the intended
|
||||
mapped/network body transport. Increasing the Unity timeout would hide the
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ drivers, asset-provider hooks, package release, runtime tests, and captures.
|
|||
- `gamecult.eve.provider_advertisement.v1`
|
||||
- `gamecult.eve.surface.v1`
|
||||
- provider asset-manifest documents
|
||||
- runtime-selected asset-variant metadata, including native rendering-program bindings
|
||||
- provider command receipts
|
||||
- semantic render-channel inclusion and exclusion policy
|
||||
- Unity input and local presentation assets
|
||||
|
|
@ -31,15 +32,18 @@ drivers, asset-provider hooks, package release, runtime tests, and captures.
|
|||
## Derived State
|
||||
|
||||
`ActiveWorld`, scene objects, transforms, markers, camera pose, native
|
||||
render-channel layer mappings, asset caches, presentation counters, and receipt
|
||||
display state are projections. They are not world truth.
|
||||
render-channel layer mappings, resolved native shader ports/passes, asset caches,
|
||||
presentation counters, and receipt display state are projections. They are not
|
||||
world truth.
|
||||
|
||||
## Forbidden Writers
|
||||
|
||||
Unity transforms, input drivers, camera rigs, scene sinks, asset caches, and
|
||||
pending receipts may not mutate or simulate provider world state. Plugin
|
||||
projection shells may not implement Sai, Norn, or TeX semantics. Portable
|
||||
surfaces may not carry Unity layer numbers or camera culling masks.
|
||||
surfaces may not carry Unity layer numbers, camera culling masks, shader property
|
||||
names, shader keywords, or native pass indices. Those bindings belong to the
|
||||
selected runtime asset variant.
|
||||
|
||||
## Shared Paths
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ param(
|
|||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$expectedEveUnityCommit = "817912a041ac1911e1e27a4b88617754d90ad4b7"
|
||||
$expectedEveUnityCommit = "5ce654800760203154132d4b0fd1475294283ba6"
|
||||
$expectedEveFieldsCommit = "382a23d8f8a07e4b5eef5f81f84655861a858367"
|
||||
$expectedEveUnityUiToolkitCommit = "4d0cbe0185bdc4fc65eb63503a7c5cb578539669"
|
||||
$expectedCultLibCommit = "feb5c71513e71d681699f462fe3682b3168c6f73"
|
||||
$repoRoot = Split-Path -Parent $PSScriptRoot
|
||||
|
|
@ -118,8 +119,27 @@ if (-not $SkipAssetBundleBuild) {
|
|||
}
|
||||
}
|
||||
|
||||
$daemonBuildLogPath = Join-Path $outputRoot "aetheria-daemon-build.log"
|
||||
$daemonBuildErrorLogPath = Join-Path $outputRoot "aetheria-daemon-build.error.log"
|
||||
$daemonBuildArguments = @(
|
||||
"build", $daemonProject,
|
||||
"-p:CultLibRoot=$CultLibRoot", "-p:EveUnityRoot=$EveUnityRoot", "-p:YmirRoot=$YmirRoot"
|
||||
)
|
||||
$previousErrorActionPreference = $ErrorActionPreference
|
||||
try {
|
||||
$ErrorActionPreference = "Continue"
|
||||
& dotnet @daemonBuildArguments 1> $daemonBuildLogPath 2> $daemonBuildErrorLogPath
|
||||
$daemonBuildExitCode = $LASTEXITCODE
|
||||
}
|
||||
finally {
|
||||
$ErrorActionPreference = $previousErrorActionPreference
|
||||
}
|
||||
if ($daemonBuildExitCode -ne 0) {
|
||||
throw "Aetheria daemon prebuild failed with exit code $daemonBuildExitCode. See $daemonBuildErrorLogPath"
|
||||
}
|
||||
|
||||
$daemonArguments = @(
|
||||
"run", "--project", $daemonProject,
|
||||
"run", "--project", $daemonProject, "--no-build",
|
||||
"-p:CultLibRoot=$CultLibRoot", "-p:EveUnityRoot=$EveUnityRoot", "-p:YmirRoot=$YmirRoot",
|
||||
"--",
|
||||
"--root", $AetheriaRoot,
|
||||
|
|
@ -204,17 +224,19 @@ try {
|
|||
$releaseLock = Get-Content -LiteralPath (Join-Path $repoRoot "ReleaseConsumerProject\Packages\packages-lock.json") -Raw | ConvertFrom-Json
|
||||
$releasedPackageClient = $projectRoot -eq "ReleaseConsumerProject"
|
||||
$sceneLock = $releaseLock.dependencies.'org.gamecult.eve.unity-scene'
|
||||
$fieldsLock = $releaseLock.dependencies.'org.gamecult.eve.plugin-fields'
|
||||
$uiToolkitLock = $releaseLock.dependencies.'org.gamecult.eve.unity-uitoolkit'
|
||||
$cultLibLock = $releaseLock.dependencies.'org.gamecult.cultlib'
|
||||
if (-not $releasedPackageClient) { throw "Released witness must run ReleaseConsumerProject, got '$projectRoot'." }
|
||||
if ($sceneLock.source -ne "git" -or $uiToolkitLock.source -ne "git" -or $cultLibLock.source -ne "git" -or
|
||||
$sceneLock.version -like "file:*" -or $uiToolkitLock.version -like "file:*" -or $cultLibLock.version -like "file:*") {
|
||||
if ($sceneLock.source -ne "git" -or $fieldsLock.source -ne "git" -or $uiToolkitLock.source -ne "git" -or $cultLibLock.source -ne "git" -or
|
||||
$sceneLock.version -like "file:*" -or $fieldsLock.version -like "file:*" -or $uiToolkitLock.version -like "file:*" -or $cultLibLock.version -like "file:*") {
|
||||
throw "Released witness resolved a non-git/local package dependency."
|
||||
}
|
||||
if ($sceneLock.hash -ne $expectedEveUnityCommit -or
|
||||
$fieldsLock.hash -ne $expectedEveFieldsCommit -or
|
||||
$uiToolkitLock.hash -ne $expectedEveUnityUiToolkitCommit -or
|
||||
$cultLibLock.hash -ne $expectedCultLibCommit) {
|
||||
throw "Released package commits do not match the witnessed releases. scene=$($sceneLock.hash) uitoolkit=$($uiToolkitLock.hash) cultlib=$($cultLibLock.hash)"
|
||||
throw "Released package commits do not match the witnessed releases. scene=$($sceneLock.hash) fields=$($fieldsLock.hash) uitoolkit=$($uiToolkitLock.hash) cultlib=$($cultLibLock.hash)"
|
||||
}
|
||||
$finalBodies = @(Get-ChildItem -LiteralPath $assetCachePath -Filter *.body -File -Recurse -ErrorAction SilentlyContinue)
|
||||
$finalPartials = @(Get-ChildItem -LiteralPath $assetCachePath -Filter *.partial -File -Recurse -ErrorAction SilentlyContinue)
|
||||
|
|
@ -234,6 +256,7 @@ try {
|
|||
$facts | Add-Member -NotePropertyName releasedPackageClient -NotePropertyValue $releasedPackageClient
|
||||
$facts | Add-Member -NotePropertyName clientProject -NotePropertyValue $projectRoot
|
||||
$facts | Add-Member -NotePropertyName eveUnityPackageCommit -NotePropertyValue $sceneLock.hash
|
||||
$facts | Add-Member -NotePropertyName eveFieldsPackageCommit -NotePropertyValue $fieldsLock.hash
|
||||
$facts | Add-Member -NotePropertyName eveUnityUiToolkitPackageCommit -NotePropertyValue $uiToolkitLock.hash
|
||||
$facts | Add-Member -NotePropertyName cultLibPackageCommit -NotePropertyValue $cultLibLock.hash
|
||||
$facts | Add-Member -NotePropertyName contentDelivery -NotePropertyValue ([ordered]@{
|
||||
|
|
|
|||
Reference in a new issue