Prove released Aetheria world lowering
This commit is contained in:
parent
474cadac1c
commit
b05e7daf05
5 changed files with 279 additions and 37 deletions
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using GameCult.Caching;
|
||||
using GameCult.Caching.MessagePack;
|
||||
using GameCult.Eve.Surface;
|
||||
|
|
@ -175,12 +176,16 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
Path.Combine(Application.temporaryCachePath, $"eve-unity-{Guid.NewGuid():N}.cc");
|
||||
var capturePath = Environment.GetEnvironmentVariable("EVEUNITY_AETHERIA_CAPTURE_PATH") ??
|
||||
Path.Combine(Application.temporaryCachePath, "aetheria-daemon-world.png");
|
||||
var mapCapturePath = Environment.GetEnvironmentVariable("EVEUNITY_AETHERIA_MAP_CAPTURE_PATH") ??
|
||||
Path.Combine(Application.temporaryCachePath, "aetheria-daemon-map.png");
|
||||
var root = new GameObject("Generic Eve World Projection");
|
||||
var cameraObject = new GameObject("Generic Eve Capture Camera");
|
||||
var mapCameraObject = new GameObject("Generic Eve Map Camera");
|
||||
var lightObject = new GameObject("Generic Eve World Light");
|
||||
RenderTexture target = null;
|
||||
Texture2D pixels = null;
|
||||
EveUnityCultMeshPlayableWorldProvider provider = null;
|
||||
EveUnityPlayableWorldClientHost host = null;
|
||||
EveUnityPlayableWorldRuntime runtime = null;
|
||||
WitnessReceipt movementReceipt = null;
|
||||
WitnessReceipt focusReceipt = null;
|
||||
|
|
@ -217,18 +222,38 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
Assert.That(provider.Selection.VerseId, Is.Not.Empty);
|
||||
Assert.That(provider.Selection.ProviderId, Is.Not.Empty);
|
||||
Assert.That(provider.Selection.SurfaceId, Is.Not.Empty);
|
||||
runtime = EveUnityPlayableWorldRuntime.CreateForGameObjectScene(
|
||||
host = root.AddComponent<EveUnityPlayableWorldClientHost>();
|
||||
host.Configure(
|
||||
root.transform,
|
||||
provider,
|
||||
provider,
|
||||
null,
|
||||
provider,
|
||||
provider,
|
||||
provider);
|
||||
var initial = runtime.Connect();
|
||||
Assert.That(initial.ActiveEntities, Is.GreaterThan(0));
|
||||
host.Connect();
|
||||
runtime = host.Runtime;
|
||||
Assert.That(runtime, Is.Not.Null);
|
||||
Assert.That(runtime.ActiveWorld.PlayerEntityId, Is.Not.Empty);
|
||||
var entityDeadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < entityDeadline &&
|
||||
(host.PresentedEntities?.CurrentGeneration == null ||
|
||||
host.PresentedEntities.CurrentGeneration.Entities.Count == 0))
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
host.Refresh();
|
||||
}
|
||||
Assert.That(host.PresentedEntities?.CurrentGeneration, Is.Not.Null);
|
||||
Assert.That(host.PresentedEntities.CurrentGeneration.Entities.Count, Is.GreaterThan(0));
|
||||
|
||||
var playerId = runtime.ActiveWorld.PlayerEntityId;
|
||||
var playerFact = host.PresentedEntities.CurrentGeneration.Entities
|
||||
.Single(entity => entity.EntityId == playerId);
|
||||
var playerPrefab = provider.ResolvePrefab(new EveUnityPlayableWorldAssetBinding(
|
||||
playerFact.AssetRef,
|
||||
playerFact.EntityKind,
|
||||
"provider-asset-ref"));
|
||||
Assert.That(playerPrefab, Is.Not.Null,
|
||||
$"Provider asset catalog did not resolve player AssetRef '{playerFact.AssetRef}'.");
|
||||
var marker = FindMarker(root, playerId);
|
||||
Assert.That(
|
||||
marker.GetComponentsInChildren<Transform>(includeInactive: true).Length,
|
||||
|
|
@ -302,6 +327,7 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
var camera = cameraObject.AddComponent<Camera>();
|
||||
camera.clearFlags = CameraClearFlags.SolidColor;
|
||||
camera.backgroundColor = new Color(0.035f, 0.055f, 0.08f, 1f);
|
||||
camera.cullingMask = -1;
|
||||
foreach (var entityMarker in root.GetComponentsInChildren<EveUnityPlayableWorldEntityMarker>())
|
||||
{
|
||||
foreach (var renderer in entityMarker.GetComponentsInChildren<Renderer>())
|
||||
|
|
@ -316,15 +342,25 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
var playerMarker = FindMarker(root, playerId);
|
||||
var playerRenderers = playerMarker.GetComponentsInChildren<Renderer>();
|
||||
Assert.That(playerRenderers, Is.Not.Empty, "The provider-authored player prefab has no renderable visual.");
|
||||
var playerBounds = playerRenderers[0].bounds;
|
||||
foreach (var renderer in playerRenderers)
|
||||
playerBounds.Encapsulate(renderer.bounds);
|
||||
var halfFovRadians = camera.fieldOfView * 0.5f * Mathf.Deg2Rad;
|
||||
var cameraDistance = Mathf.Max(8f, playerBounds.extents.magnitude / Mathf.Tan(halfFovRadians) * 1.35f);
|
||||
camera.nearClipPlane = Mathf.Max(0.01f, cameraDistance * 0.001f);
|
||||
camera.farClipPlane = Mathf.Max(1000f, cameraDistance + playerBounds.size.magnitude * 4f);
|
||||
camera.transform.position = playerBounds.center + new Vector3(1f, 0.65f, -1.2f).normalized * cameraDistance;
|
||||
camera.transform.LookAt(playerBounds.center);
|
||||
Assert.That(provider.TryGetRenderChannelLayer("map", out var mapLayer), Is.True);
|
||||
var mapRenderers = new List<Renderer>();
|
||||
foreach (var renderer in root.GetComponentsInChildren<Renderer>(includeInactive: true))
|
||||
{
|
||||
if (renderer.gameObject.layer == mapLayer)
|
||||
mapRenderers.Add(renderer);
|
||||
}
|
||||
Assert.That(mapRenderers, Is.Not.Empty, "The live provider prefab has no renderer assigned to its advertised map channel.");
|
||||
|
||||
var cameraRig = cameraObject.AddComponent<EveUnityPlayableWorldCameraRig>();
|
||||
cameraRig.Host = host;
|
||||
cameraRig.CameraTransform = camera.transform;
|
||||
cameraRig.RenderPolicySource = provider;
|
||||
Assert.That(cameraRig.ApplyRig(0f), Is.True);
|
||||
Assert.That(camera.cullingMask & (1 << mapLayer), Is.Zero);
|
||||
|
||||
var mapCamera = mapCameraObject.AddComponent<Camera>();
|
||||
mapCamera.cullingMask = 1 << mapLayer;
|
||||
Assert.That(mapCamera.cullingMask & (1 << mapLayer), Is.Not.Zero);
|
||||
target = new RenderTexture(640, 360, 24, RenderTextureFormat.ARGB32);
|
||||
camera.targetTexture = target;
|
||||
yield return null;
|
||||
|
|
@ -336,10 +372,36 @@ 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));
|
||||
|
||||
var mapBounds = mapRenderers[0].bounds;
|
||||
foreach (var renderer in mapRenderers)
|
||||
mapBounds.Encapsulate(renderer.bounds);
|
||||
mapCamera.clearFlags = CameraClearFlags.SolidColor;
|
||||
mapCamera.backgroundColor = camera.backgroundColor;
|
||||
mapCamera.orthographic = true;
|
||||
mapCamera.orthographicSize = Mathf.Max(0.1f, mapBounds.extents.x, mapBounds.extents.z) * 1.25f;
|
||||
mapCamera.nearClipPlane = 0.01f;
|
||||
mapCamera.farClipPlane = Mathf.Max(10f, mapBounds.size.magnitude * 4f);
|
||||
mapCamera.transform.position = mapBounds.center + Vector3.up * (mapCamera.farClipPlane * 0.25f);
|
||||
mapCamera.transform.rotation = Quaternion.Euler(90f, 0f, 0f);
|
||||
mapCamera.targetTexture = target;
|
||||
mapCamera.Render();
|
||||
RenderTexture.active = target;
|
||||
pixels.ReadPixels(new Rect(0, 0, 640, 360), 0, 0);
|
||||
pixels.Apply();
|
||||
var mapChangedPixels = CountChangedPixels(pixels, mapCamera.backgroundColor);
|
||||
Assert.That(mapChangedPixels, Is.GreaterThan(25), "The map-only camera rendered no provider-authored map glyph pixels.");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(mapCapturePath)));
|
||||
File.WriteAllBytes(mapCapturePath, pixels.EncodeToPNG());
|
||||
Assert.That(new FileInfo(mapCapturePath).Length, Is.GreaterThan(1024));
|
||||
WriteWitnessFacts(
|
||||
initialVersion,
|
||||
runtime.ActiveVersion,
|
||||
movementDistance,
|
||||
mapRenderers.Count,
|
||||
mapChangedPixels,
|
||||
(camera.cullingMask & (1 << mapLayer)) == 0,
|
||||
(mapCamera.cullingMask & (1 << mapLayer)) != 0,
|
||||
movementReceipt,
|
||||
focusReceipt,
|
||||
actionReceipt);
|
||||
|
|
@ -349,10 +411,13 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
RenderTexture.active = null;
|
||||
var camera = cameraObject.GetComponent<Camera>();
|
||||
if (camera != null) camera.targetTexture = null;
|
||||
var mapCamera = mapCameraObject.GetComponent<Camera>();
|
||||
if (mapCamera != null) mapCamera.targetTexture = null;
|
||||
if (target != null) UnityEngine.Object.DestroyImmediate(target);
|
||||
if (pixels != null) UnityEngine.Object.DestroyImmediate(pixels);
|
||||
runtime?.Dispose();
|
||||
host?.Disconnect();
|
||||
UnityEngine.Object.DestroyImmediate(lightObject);
|
||||
UnityEngine.Object.DestroyImmediate(mapCameraObject);
|
||||
UnityEngine.Object.DestroyImmediate(cameraObject);
|
||||
UnityEngine.Object.DestroyImmediate(root);
|
||||
}
|
||||
|
|
@ -362,6 +427,10 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
long initialVersion,
|
||||
long finalVersion,
|
||||
float movementDistance,
|
||||
int mapChannelRendererCount,
|
||||
int mapChangedPixels,
|
||||
bool pilotCameraExcludesMapChannel,
|
||||
bool mapCameraIncludesMapChannel,
|
||||
WitnessReceipt movement,
|
||||
WitnessReceipt targeting,
|
||||
WitnessReceipt action)
|
||||
|
|
@ -378,6 +447,10 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
initialVersion = initialVersion,
|
||||
finalVersion = finalVersion,
|
||||
movementDistance = movementDistance,
|
||||
mapChannelRendererCount = mapChannelRendererCount,
|
||||
mapChangedPixels = mapChangedPixels,
|
||||
pilotCameraExcludesMapChannel = pilotCameraExcludesMapChannel,
|
||||
mapCameraIncludesMapChannel = mapCameraIncludesMapChannel,
|
||||
receipts = new[] { movement, targeting, action }
|
||||
};
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path)));
|
||||
|
|
@ -395,6 +468,10 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
public long initialVersion;
|
||||
public long finalVersion;
|
||||
public float movementDistance;
|
||||
public int mapChannelRendererCount;
|
||||
public int mapChangedPixels;
|
||||
public bool pilotCameraExcludesMapChannel;
|
||||
public bool mapCameraIncludesMapChannel;
|
||||
public WitnessReceipt[] receipts;
|
||||
}
|
||||
|
||||
|
|
@ -428,6 +505,19 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
throw new InvalidOperationException($"Projected world has no entity marker '{entityId}'.");
|
||||
}
|
||||
|
||||
private static int CountChangedPixels(Texture2D texture, Color background)
|
||||
{
|
||||
var changed = 0;
|
||||
foreach (var pixel in texture.GetPixels())
|
||||
{
|
||||
if (Mathf.Abs(pixel.r - background.r) +
|
||||
Mathf.Abs(pixel.g - background.g) +
|
||||
Mathf.Abs(pixel.b - background.b) > 0.08f)
|
||||
changed++;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
private static EveUnitySceneProviderSurfaceDocument WorldDocument()
|
||||
{
|
||||
var entities = new[]
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@
|
|||
"com.unity.modules.imageconversion": "1.0.0",
|
||||
"com.unity.modules.physics": "1.0.0",
|
||||
"com.unity.modules.uielements": "1.0.0",
|
||||
"org.gamecult.cultlib": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.8",
|
||||
"com.unity.render-pipelines.universal": "17.4.0",
|
||||
"org.gamecult.cultlib": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.10",
|
||||
"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.1.1",
|
||||
"org.gamecult.eve.surface": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.surface#eveunity-surface-v0.2.0",
|
||||
"org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.2.0",
|
||||
"org.gamecult.eve.surface": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.surface#eveunity-surface-v0.2.1",
|
||||
"org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.15",
|
||||
"org.gamecult.eve.unity-uitoolkit": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-uitoolkit#eveunity-uitoolkit-v0.1.0"
|
||||
},
|
||||
"testables": [
|
||||
|
|
|
|||
|
|
@ -1,5 +1,27 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"com.unity.burst": {
|
||||
"version": "1.8.29",
|
||||
"depth": 2,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.mathematics": "1.2.1",
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.collections": {
|
||||
"version": "6.4.0",
|
||||
"depth": 2,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.burst": "1.8.23",
|
||||
"com.unity.mathematics": "1.3.2",
|
||||
"com.unity.nuget.mono-cecil": "1.11.5",
|
||||
"com.unity.test-framework": "1.4.6",
|
||||
"com.unity.test-framework.performance": "3.0.3"
|
||||
}
|
||||
},
|
||||
"com.unity.ext.nunit": {
|
||||
"version": "2.0.5",
|
||||
"depth": 1,
|
||||
|
|
@ -13,6 +35,60 @@
|
|||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.nuget.mono-cecil": {
|
||||
"version": "1.11.6",
|
||||
"depth": 3,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.render-pipelines.core": {
|
||||
"version": "17.4.0",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.burst": "1.8.14",
|
||||
"com.unity.mathematics": "1.3.2",
|
||||
"com.unity.ugui": "2.0.0",
|
||||
"com.unity.collections": "2.4.3",
|
||||
"com.unity.modules.terrain": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.render-pipelines.universal": {
|
||||
"version": "17.4.0",
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.render-pipelines.core": "17.4.0",
|
||||
"com.unity.shadergraph": "17.4.0",
|
||||
"com.unity.render-pipelines.universal-config": "17.4.0"
|
||||
}
|
||||
},
|
||||
"com.unity.render-pipelines.universal-config": {
|
||||
"version": "17.4.0",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.render-pipelines.core": "17.4.0"
|
||||
}
|
||||
},
|
||||
"com.unity.searcher": {
|
||||
"version": "4.9.4",
|
||||
"depth": 2,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.shadergraph": {
|
||||
"version": "17.4.0",
|
||||
"depth": 1,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.render-pipelines.core": "17.4.0",
|
||||
"com.unity.searcher": "4.9.3"
|
||||
}
|
||||
},
|
||||
"com.unity.test-framework": {
|
||||
"version": "1.6.0",
|
||||
"depth": 0,
|
||||
|
|
@ -23,12 +99,31 @@
|
|||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
}
|
||||
},
|
||||
"com.unity.test-framework.performance": {
|
||||
"version": "3.4.0",
|
||||
"depth": 3,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.test-framework": "1.1.33",
|
||||
"com.unity.modules.jsonserialize": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.ugui": {
|
||||
"version": "2.0.0",
|
||||
"depth": 2,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.modules.ui": "1.0.0",
|
||||
"com.unity.modules.imgui": "1.0.0"
|
||||
}
|
||||
},
|
||||
"org.gamecult.cultlib": {
|
||||
"version": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.7",
|
||||
"version": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.10",
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {},
|
||||
"hash": "1f8f832a788e2bdf59df90fb91da583574d3a42d"
|
||||
"hash": "085aa2c0756328770623474c4e9fbacd7218b390"
|
||||
},
|
||||
"org.gamecult.eve.plugin-fields": {
|
||||
"version": "https://github.com/GameCult/EvePlugins.git?path=/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields#eve-plugin-fields-unity-v0.1.1",
|
||||
|
|
@ -38,25 +133,25 @@
|
|||
"hash": "0b099274a4e2b4c301eced4322166837792f585a"
|
||||
},
|
||||
"org.gamecult.eve.surface": {
|
||||
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.surface#b6f001b300a88aff0bc13372b5c1dbc2002954f8",
|
||||
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.surface#eveunity-surface-v0.2.1",
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {
|
||||
"org.gamecult.cultlib": "1.0.6"
|
||||
"org.gamecult.cultlib": "1.0.8"
|
||||
},
|
||||
"hash": "b6f001b300a88aff0bc13372b5c1dbc2002954f8"
|
||||
"hash": "d0aa50d31f3b6da96bffc194fdc3aa358f37e332"
|
||||
},
|
||||
"org.gamecult.eve.unity-scene": {
|
||||
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#b6f001b300a88aff0bc13372b5c1dbc2002954f8",
|
||||
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.15",
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {
|
||||
"org.gamecult.cultlib": "1.0.6",
|
||||
"org.gamecult.cultlib": "1.0.10",
|
||||
"org.gamecult.eve.plugin-fields": "0.1.1",
|
||||
"org.gamecult.eve.surface": "0.1.0",
|
||||
"org.gamecult.eve.surface": "0.2.1",
|
||||
"com.unity.mathematics": "1.3.2"
|
||||
},
|
||||
"hash": "b6f001b300a88aff0bc13372b5c1dbc2002954f8"
|
||||
"hash": "474cadac1c173e24b2c9b9ddde7b781059dbae4c"
|
||||
},
|
||||
"org.gamecult.eve.unity-uitoolkit": {
|
||||
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-uitoolkit#eveunity-uitoolkit-v0.1.0",
|
||||
|
|
@ -103,6 +198,12 @@
|
|||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.terrain": {
|
||||
"version": "1.0.0",
|
||||
"depth": 2,
|
||||
"source": "builtin",
|
||||
"dependencies": {}
|
||||
},
|
||||
"com.unity.modules.ui": {
|
||||
"version": "1.0.0",
|
||||
"depth": 1,
|
||||
|
|
|
|||
18
docs/aetheria-released-package-witness.md
Normal file
18
docs/aetheria-released-package-witness.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Aetheria released-package witness
|
||||
|
||||
The warm-cache witness passes against `org.gamecult.eve.unity-scene` `0.3.15`
|
||||
at commit `474cadac1c173e24b2c9b9ddde7b781059dbae4c`.
|
||||
|
||||
Evidence is in `artifacts/render-channel-witness-41`:
|
||||
|
||||
- `results.xml`: one passing PlayMode witness.
|
||||
- `aetheria-daemon-world.png`: provider-authored 3D pilot view.
|
||||
- `aetheria-daemon-map.png`: map-channel-only view.
|
||||
- `witness-facts.json`: movement, targeting, action, receipts, and camera-mask facts.
|
||||
- `runtime-witness.warm.json`: released package and screenshot hashes.
|
||||
|
||||
The cold CDN path is not proven. `artifacts/render-channel-witness-21/results.xml`
|
||||
records a timeout while fetching the 13,006,384-byte bundle through batches of
|
||||
32 `gamecult.mesh.cdn_artifact_chunk.v1` snapshot records. The bundle must move
|
||||
through the intended mapped/network body transport; increasing the snapshot
|
||||
timeout is not an accepted fix.
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
param(
|
||||
[string] $UnityExe = "C:\Program Files\Unity\Hub\Editor\6000.4.2f1\Editor\Unity.exe",
|
||||
[string] $AetheriaRoot = "E:\Projects\Aetheria",
|
||||
[string] $CultLibRoot = "E:\Projects\CultLib",
|
||||
[string] $EveUnityRoot = "E:\Projects\EveUnity",
|
||||
[string] $ClientProject = "ReleaseConsumerProject",
|
||||
[int] $Port = 3076,
|
||||
[string] $OutputDirectory = "artifacts\aetheria-daemon",
|
||||
|
|
@ -18,6 +20,7 @@ $unityLogPath = Join-Path $outputRoot "unity.log"
|
|||
$bundleBuildLogPath = Join-Path $outputRoot "asset-bundle-build.log"
|
||||
$daemonLogPath = Join-Path $outputRoot "aetheria-daemon.log"
|
||||
$capturePath = Join-Path $outputRoot "aetheria-daemon-world.png"
|
||||
$mapCapturePath = Join-Path $outputRoot "aetheria-daemon-map.png"
|
||||
$factsPath = Join-Path $outputRoot "witness-facts.json"
|
||||
$witnessPath = Join-Path $outputRoot "runtime-witness.json"
|
||||
$replicaPath = Join-Path $outputRoot "eve-unity-replica.cc"
|
||||
|
|
@ -55,13 +58,24 @@ foreach ($ephemeralPath in @(
|
|||
if (Test-Path -LiteralPath $resolved) { Remove-Item -LiteralPath $resolved -Recurse -Force }
|
||||
}
|
||||
|
||||
$import = Start-Process -FilePath "dotnet" -ArgumentList @(
|
||||
"run", "--project", $importProject, "--", $AetheriaRoot, $statePath
|
||||
) -PassThru -WindowStyle Hidden -Wait `
|
||||
-RedirectStandardOutput (Join-Path $outputRoot "aetheria-import.log") `
|
||||
-RedirectStandardError (Join-Path $outputRoot "aetheria-import.error.log")
|
||||
if ($import.ExitCode -ne 0) {
|
||||
throw "Aetheria state import failed with exit code $($import.ExitCode). See $outputRoot\aetheria-import.error.log"
|
||||
$importArguments = @(
|
||||
"run", "--project", $importProject,
|
||||
"-p:CultLibRoot=$CultLibRoot", "-p:EveUnityRoot=$EveUnityRoot",
|
||||
"--", $AetheriaRoot, $statePath
|
||||
)
|
||||
$importLogPath = Join-Path $outputRoot "aetheria-import.log"
|
||||
$importErrorLogPath = Join-Path $outputRoot "aetheria-import.error.log"
|
||||
$previousErrorActionPreference = $ErrorActionPreference
|
||||
try {
|
||||
$ErrorActionPreference = "Continue"
|
||||
& dotnet @importArguments 1> $importLogPath 2> $importErrorLogPath
|
||||
$importExitCode = $LASTEXITCODE
|
||||
}
|
||||
finally {
|
||||
$ErrorActionPreference = $previousErrorActionPreference
|
||||
}
|
||||
if ($importExitCode -ne 0) {
|
||||
throw "Aetheria state import failed with exit code $importExitCode. See $importErrorLogPath"
|
||||
}
|
||||
if (-not $SkipAssetBundleBuild) {
|
||||
$bundleBuilder = Start-Process -FilePath $UnityExe -ArgumentList @(
|
||||
|
|
@ -83,7 +97,9 @@ if (-not $SkipAssetBundleBuild) {
|
|||
}
|
||||
|
||||
$daemonArguments = @(
|
||||
"run", "--project", $daemonProject, "--",
|
||||
"run", "--project", $daemonProject,
|
||||
"-p:CultLibRoot=$CultLibRoot", "-p:EveUnityRoot=$EveUnityRoot",
|
||||
"--",
|
||||
"--root", $AetheriaRoot,
|
||||
"--state", $statePath,
|
||||
"--client-cultmesh-host", "127.0.0.1",
|
||||
|
|
@ -112,10 +128,12 @@ try {
|
|||
if (-not $ready) { throw "Aetheria daemon did not open CultMesh port $Port. See $daemonLogPath" }
|
||||
|
||||
$env:EVEUNITY_RENDEZVOUS_ENDPOINT = "rudp://127.0.0.1:$Port"
|
||||
Remove-Item Env:EVEUNITY_PROVIDER_ID -ErrorAction SilentlyContinue
|
||||
$env:EVEUNITY_PROVIDER_ID = "aetheria"
|
||||
Remove-Item Env:EVEUNITY_SURFACE_ID -ErrorAction SilentlyContinue
|
||||
$env:EVEUNITY_REPLICA_PATH = $replicaPath
|
||||
$env:EVEUNITY_AETHERIA_CAPTURE_PATH = $capturePath
|
||||
$env:EVEUNITY_AETHERIA_MAP_CAPTURE_PATH = $mapCapturePath
|
||||
$env:EVEUNITY_DISABLE_AUTO_LAUNCHER = "1"
|
||||
$env:EVEUNITY_ASSET_CACHE_PATH = $assetCachePath
|
||||
$env:EVEUNITY_WITNESS_FACTS_PATH = $factsPath
|
||||
$arguments = @(
|
||||
|
|
@ -135,6 +153,7 @@ try {
|
|||
$run = $results.SelectSingleNode("//test-run")
|
||||
if ($null -eq $run -or [int]$run.passed -ne 1 -or [int]$run.failed -ne 0) { throw "Live world witness did not pass: $resultsPath" }
|
||||
if (-not (Test-Path $capturePath) -or (Get-Item $capturePath).Length -lt 1024) { throw "Live world capture is missing: $capturePath" }
|
||||
if (-not (Test-Path $mapCapturePath) -or (Get-Item $mapCapturePath).Length -lt 1024) { throw "Live map-channel capture is missing: $mapCapturePath" }
|
||||
if (-not (Test-Path $factsPath)) { throw "Live world witness facts are missing: $factsPath" }
|
||||
$facts = Get-Content -LiteralPath $factsPath -Raw | ConvertFrom-Json
|
||||
$releaseLock = Get-Content -LiteralPath (Join-Path $repoRoot "ReleaseConsumerProject\Packages\packages-lock.json") -Raw | ConvertFrom-Json
|
||||
|
|
@ -144,6 +163,7 @@ try {
|
|||
$facts | Add-Member -NotePropertyName eveUnityPackageCommit -NotePropertyValue $releaseLock.dependencies.'org.gamecult.eve.unity-scene'.hash
|
||||
$facts | Add-Member -NotePropertyName cultLibPackageCommit -NotePropertyValue $releaseLock.dependencies.'org.gamecult.cultlib'.hash
|
||||
$capture = Get-Item -LiteralPath $capturePath
|
||||
$mapCapture = Get-Item -LiteralPath $mapCapturePath
|
||||
$resultsArtifact = Get-Item -LiteralPath $resultsPath
|
||||
$durationMs = [Math]::Round(([DateTimeOffset]::UtcNow - $witnessStartedAt).TotalMilliseconds, 3)
|
||||
$testDurationMs = [Math]::Round(([double]$run.duration) * 1000, 3)
|
||||
|
|
@ -152,7 +172,7 @@ try {
|
|||
witnessId = "eveunity.aetheria.game.$observedCacheState"
|
||||
runtimeId = "unity-scene"
|
||||
runtimeOwnerRepo = "EveUnity"
|
||||
providerId = "aetheria.daemon"
|
||||
providerId = "aetheria"
|
||||
surfaceId = "aetheria.game"
|
||||
projectionKind = "provider-authored-world-surface"
|
||||
status = "pass"
|
||||
|
|
@ -169,6 +189,9 @@ try {
|
|||
height = 360
|
||||
encodedSizeBytes = $capture.Length
|
||||
sha256 = (Get-FileHash -LiteralPath $capture.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
mapEncodedSizeBytes = $mapCapture.Length
|
||||
mapSha256 = (Get-FileHash -LiteralPath $mapCapture.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
mapChangedPixels = $facts.mapChangedPixels
|
||||
}
|
||||
artifacts = @(
|
||||
[ordered]@{
|
||||
|
|
@ -179,6 +202,14 @@ try {
|
|||
width = 640
|
||||
height = 360
|
||||
},
|
||||
[ordered]@{
|
||||
kind = "unity-map-channel-png"
|
||||
path = $mapCapture.Name
|
||||
sha256 = (Get-FileHash -LiteralPath $mapCapture.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
sizeBytes = $mapCapture.Length
|
||||
width = 640
|
||||
height = 360
|
||||
},
|
||||
[ordered]@{
|
||||
kind = "unity-test-results"
|
||||
path = $resultsArtifact.Name
|
||||
|
|
@ -193,11 +224,12 @@ try {
|
|||
$witness | ConvertTo-Json -Depth 12 | Set-Content -LiteralPath $stateWitnessPath -Encoding UTF8
|
||||
Write-Host "Aetheria daemon world witness: passed"
|
||||
Write-Host "Capture: $capturePath"
|
||||
Write-Host "Map capture: $mapCapturePath"
|
||||
Write-Host "Runtime witness: $witnessPath"
|
||||
Write-Host "Cache-state witness: $stateWitnessPath"
|
||||
}
|
||||
finally {
|
||||
if ($null -ne $daemon -and -not $daemon.HasExited) { Stop-Process -Id $daemon.Id -Force }
|
||||
Remove-Item Env:EVEUNITY_RENDEZVOUS_ENDPOINT, Env:EVEUNITY_PROVIDER_ENDPOINT, Env:EVEUNITY_PROVIDER_ID, Env:EVEUNITY_SURFACE_ID, Env:EVEUNITY_REPLICA_PATH, Env:EVEUNITY_AETHERIA_CAPTURE_PATH, Env:EVEUNITY_ASSET_CACHE_PATH, Env:EVEUNITY_WITNESS_FACTS_PATH -ErrorAction SilentlyContinue
|
||||
Remove-Item Env:EVEUNITY_RENDEZVOUS_ENDPOINT, Env:EVEUNITY_PROVIDER_ENDPOINT, Env:EVEUNITY_PROVIDER_ID, Env:EVEUNITY_SURFACE_ID, Env:EVEUNITY_REPLICA_PATH, Env:EVEUNITY_AETHERIA_CAPTURE_PATH, Env:EVEUNITY_AETHERIA_MAP_CAPTURE_PATH, Env:EVEUNITY_DISABLE_AUTO_LAUNCHER, Env:EVEUNITY_ASSET_CACHE_PATH, Env:EVEUNITY_WITNESS_FACTS_PATH -ErrorAction SilentlyContinue
|
||||
Remove-Item Env:AETHERIA_TRACE_EVE_SNAPSHOTS -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue