Prove released split-bundle Aetheria sessions
This commit is contained in:
parent
3632bfb335
commit
45b828d5b3
6 changed files with 219 additions and 206 deletions
|
|
@ -526,45 +526,48 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
Is.GreaterThan(1),
|
||||
"The generic client substituted its primitive fallback instead of the provider-authored AssetBundle prefab.");
|
||||
|
||||
var initialPosition = marker.transform.position;
|
||||
initialVersion = runtime.ActiveVersion;
|
||||
var request = runtime.SubmitMoveVectorIntent(playerId, 1f, 0f, 1f);
|
||||
|
||||
var deadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < deadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != request.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase) ||
|
||||
runtime.ActiveVersion <= initialVersion ||
|
||||
Vector3.Distance(FindMarker(root, playerId).transform.position, initialPosition) < 0.01f))
|
||||
if (requireSessionGameplay)
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
}
|
||||
var initialPosition = marker.transform.position;
|
||||
var request = runtime.SubmitMoveVectorIntent(playerId, 1f, 0f, 1f);
|
||||
|
||||
AssertReconciledProviderReceipt(
|
||||
runtime.LastReceipt,
|
||||
request.CommandId,
|
||||
provider.Selection.ProviderId,
|
||||
provider.Selection.SurfaceId,
|
||||
initialVersion);
|
||||
Assert.That(runtime.ActiveVersion, Is.GreaterThan(initialVersion));
|
||||
Assert.That(runtime.ActiveVersion, Is.GreaterThanOrEqualTo(runtime.LastReceipt.SourceVersion));
|
||||
movementDistance = Vector3.Distance(FindMarker(root, playerId).transform.position, initialPosition);
|
||||
Assert.That(movementDistance, Is.GreaterThan(0.01f));
|
||||
movementReceipt = WitnessReceipt.From("movement", runtime.LastReceipt);
|
||||
var deadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < deadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != request.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase) ||
|
||||
runtime.ActiveVersion <= initialVersion ||
|
||||
Vector3.Distance(FindMarker(root, playerId).transform.position, initialPosition) < 0.01f))
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
}
|
||||
|
||||
var releaseVersion = runtime.ActiveVersion;
|
||||
var release = runtime.SubmitMoveVectorIntent(playerId, 0f, 0f, 0f);
|
||||
var releaseDeadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < releaseDeadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != release.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
AssertReconciledProviderReceipt(
|
||||
runtime.LastReceipt,
|
||||
request.CommandId,
|
||||
provider.Selection.ProviderId,
|
||||
provider.Selection.SurfaceId,
|
||||
initialVersion);
|
||||
Assert.That(runtime.ActiveVersion, Is.GreaterThan(initialVersion));
|
||||
Assert.That(runtime.ActiveVersion, Is.GreaterThanOrEqualTo(runtime.LastReceipt.SourceVersion));
|
||||
movementDistance = Vector3.Distance(FindMarker(root, playerId).transform.position, initialPosition);
|
||||
Assert.That(movementDistance, Is.GreaterThan(0.01f));
|
||||
movementReceipt = WitnessReceipt.From("movement", runtime.LastReceipt);
|
||||
|
||||
var releaseVersion = runtime.ActiveVersion;
|
||||
var release = runtime.SubmitMoveVectorIntent(playerId, 0f, 0f, 0f);
|
||||
var releaseDeadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < releaseDeadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != release.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
}
|
||||
AssertReconciledProviderReceipt(runtime.LastReceipt, release.CommandId,
|
||||
provider.Selection.ProviderId, provider.Selection.SurfaceId, releaseVersion);
|
||||
}
|
||||
AssertReconciledProviderReceipt(runtime.LastReceipt, release.CommandId,
|
||||
provider.Selection.ProviderId, provider.Selection.SurfaceId, releaseVersion);
|
||||
|
||||
if (requireSessionGameplay)
|
||||
{
|
||||
|
|
@ -924,7 +927,8 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
.Where(material => material != null)
|
||||
.Distinct()
|
||||
.Count(HasAnyTexture);
|
||||
Assert.That(texturedPlayerMaterialCount, Is.GreaterThanOrEqualTo(8),
|
||||
var expectedTexturedPlayerMaterialCount = requireSessionGameplay ? 8 : 7;
|
||||
Assert.That(texturedPlayerMaterialCount, Is.GreaterThanOrEqualTo(expectedTexturedPlayerMaterialCount),
|
||||
"The provider bundle must retain its advertised native material textures.");
|
||||
var directionalLightIntensity = UnityEngine.Object.FindObjectsOfType<Light>()
|
||||
.Where(light => light != null && light.enabled && light.type == LightType.Directional)
|
||||
|
|
@ -1015,25 +1019,28 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
File.WriteAllBytes(mapCapturePath, pixels.EncodeToPNG());
|
||||
Assert.That(new FileInfo(mapCapturePath).Length, Is.GreaterThan(1024));
|
||||
Debug.Log($"EveUnity witness phase map-capture took {mapCaptureElapsed.Elapsed.TotalMilliseconds:0.###}ms.");
|
||||
var tractorReleaseVersion = runtime.ActiveVersion;
|
||||
var tractorRelease = host.SubmitAdvertisedActionValueIntent(
|
||||
playerId,
|
||||
beamPresentation.ActivationActionId,
|
||||
0f);
|
||||
var tractorReleaseDeadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < tractorReleaseDeadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != tractorRelease.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase) ||
|
||||
runtime.ActiveVersion < runtime.LastReceipt.SourceVersion))
|
||||
if (requireSessionGameplay)
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
var tractorReleaseVersion = runtime.ActiveVersion;
|
||||
var tractorRelease = host.SubmitAdvertisedActionValueIntent(
|
||||
playerId,
|
||||
beamPresentation.ActivationActionId,
|
||||
0f);
|
||||
var tractorReleaseDeadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < tractorReleaseDeadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != tractorRelease.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase) ||
|
||||
runtime.ActiveVersion < runtime.LastReceipt.SourceVersion))
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
}
|
||||
AssertReconciledProviderReceipt(runtime.LastReceipt, tractorRelease.CommandId,
|
||||
provider.Selection.ProviderId, provider.Selection.SurfaceId, tractorReleaseVersion);
|
||||
tractorReleaseReceipt = WitnessReceipt.From("beam-release", runtime.LastReceipt);
|
||||
beamRenderer.RefreshNow();
|
||||
Assert.That(beamRenderer.TryGetPower(beamPresentation.Id, out tractorReleasedPower), Is.True);
|
||||
}
|
||||
AssertReconciledProviderReceipt(runtime.LastReceipt, tractorRelease.CommandId,
|
||||
provider.Selection.ProviderId, provider.Selection.SurfaceId, tractorReleaseVersion);
|
||||
tractorReleaseReceipt = WitnessReceipt.From("beam-release", runtime.LastReceipt);
|
||||
beamRenderer.RefreshNow();
|
||||
Assert.That(beamRenderer.TryGetPower(beamPresentation.Id, out tractorReleasedPower), Is.True);
|
||||
var fieldVolume = root.GetComponent<EveUnityFieldsVolumeRenderer>();
|
||||
Assert.That(fieldVolume, Is.Not.Null, "The generic client did not install its Fields volume lowerer.");
|
||||
Assert.That(fieldVolume.PresentedFrameId, Is.GreaterThanOrEqualTo(0),
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@
|
|||
"com.unity.modules.physics": "1.0.0",
|
||||
"com.unity.modules.uielements": "1.0.0",
|
||||
"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.39",
|
||||
"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.99",
|
||||
"org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.100",
|
||||
"org.gamecult.eve.unity-uitoolkit": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-uitoolkit#eveunity-uitoolkit-v0.1.1"
|
||||
},
|
||||
"testables": [
|
||||
|
|
|
|||
|
|
@ -119,11 +119,11 @@
|
|||
}
|
||||
},
|
||||
"org.gamecult.cultlib": {
|
||||
"version": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.39",
|
||||
"version": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.43",
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {},
|
||||
"hash": "54e2e69ff7f4f5e0a1316bb047c315e65ed2a185"
|
||||
"hash": "f67f5122ed1bd11da016e7b820ed60145ccd0299"
|
||||
},
|
||||
"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.2.3",
|
||||
|
|
@ -144,18 +144,18 @@
|
|||
"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.99",
|
||||
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.100",
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {
|
||||
"org.gamecult.cultlib": "1.0.39",
|
||||
"org.gamecult.cultlib": "1.0.43",
|
||||
"org.gamecult.eve.plugin-fields": "0.2.3",
|
||||
"org.gamecult.eve.surface": "0.2.4",
|
||||
"com.unity.mathematics": "1.3.2",
|
||||
"com.unity.render-pipelines.universal": "17.4.0",
|
||||
"com.unity.modules.particlesystem": "1.0.0"
|
||||
},
|
||||
"hash": "91eaa95ad45897f4322a8823a1bc5cddcee59649"
|
||||
"hash": "3632bfb3354065b78a90b921d7025c4c3fa92be4"
|
||||
},
|
||||
"org.gamecult.eve.unity-uitoolkit": {
|
||||
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-uitoolkit#eveunity-uitoolkit-v0.1.1",
|
||||
|
|
|
|||
|
|
@ -526,45 +526,48 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
Is.GreaterThan(1),
|
||||
"The generic client substituted its primitive fallback instead of the provider-authored AssetBundle prefab.");
|
||||
|
||||
var initialPosition = marker.transform.position;
|
||||
initialVersion = runtime.ActiveVersion;
|
||||
var request = runtime.SubmitMoveVectorIntent(playerId, 1f, 0f, 1f);
|
||||
|
||||
var deadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < deadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != request.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase) ||
|
||||
runtime.ActiveVersion <= initialVersion ||
|
||||
Vector3.Distance(FindMarker(root, playerId).transform.position, initialPosition) < 0.01f))
|
||||
if (requireSessionGameplay)
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
}
|
||||
var initialPosition = marker.transform.position;
|
||||
var request = runtime.SubmitMoveVectorIntent(playerId, 1f, 0f, 1f);
|
||||
|
||||
AssertReconciledProviderReceipt(
|
||||
runtime.LastReceipt,
|
||||
request.CommandId,
|
||||
provider.Selection.ProviderId,
|
||||
provider.Selection.SurfaceId,
|
||||
initialVersion);
|
||||
Assert.That(runtime.ActiveVersion, Is.GreaterThan(initialVersion));
|
||||
Assert.That(runtime.ActiveVersion, Is.GreaterThanOrEqualTo(runtime.LastReceipt.SourceVersion));
|
||||
movementDistance = Vector3.Distance(FindMarker(root, playerId).transform.position, initialPosition);
|
||||
Assert.That(movementDistance, Is.GreaterThan(0.01f));
|
||||
movementReceipt = WitnessReceipt.From("movement", runtime.LastReceipt);
|
||||
var deadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < deadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != request.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase) ||
|
||||
runtime.ActiveVersion <= initialVersion ||
|
||||
Vector3.Distance(FindMarker(root, playerId).transform.position, initialPosition) < 0.01f))
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
}
|
||||
|
||||
var releaseVersion = runtime.ActiveVersion;
|
||||
var release = runtime.SubmitMoveVectorIntent(playerId, 0f, 0f, 0f);
|
||||
var releaseDeadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < releaseDeadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != release.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
AssertReconciledProviderReceipt(
|
||||
runtime.LastReceipt,
|
||||
request.CommandId,
|
||||
provider.Selection.ProviderId,
|
||||
provider.Selection.SurfaceId,
|
||||
initialVersion);
|
||||
Assert.That(runtime.ActiveVersion, Is.GreaterThan(initialVersion));
|
||||
Assert.That(runtime.ActiveVersion, Is.GreaterThanOrEqualTo(runtime.LastReceipt.SourceVersion));
|
||||
movementDistance = Vector3.Distance(FindMarker(root, playerId).transform.position, initialPosition);
|
||||
Assert.That(movementDistance, Is.GreaterThan(0.01f));
|
||||
movementReceipt = WitnessReceipt.From("movement", runtime.LastReceipt);
|
||||
|
||||
var releaseVersion = runtime.ActiveVersion;
|
||||
var release = runtime.SubmitMoveVectorIntent(playerId, 0f, 0f, 0f);
|
||||
var releaseDeadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < releaseDeadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != release.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
}
|
||||
AssertReconciledProviderReceipt(runtime.LastReceipt, release.CommandId,
|
||||
provider.Selection.ProviderId, provider.Selection.SurfaceId, releaseVersion);
|
||||
}
|
||||
AssertReconciledProviderReceipt(runtime.LastReceipt, release.CommandId,
|
||||
provider.Selection.ProviderId, provider.Selection.SurfaceId, releaseVersion);
|
||||
|
||||
if (requireSessionGameplay)
|
||||
{
|
||||
|
|
@ -924,7 +927,8 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
.Where(material => material != null)
|
||||
.Distinct()
|
||||
.Count(HasAnyTexture);
|
||||
Assert.That(texturedPlayerMaterialCount, Is.GreaterThanOrEqualTo(8),
|
||||
var expectedTexturedPlayerMaterialCount = requireSessionGameplay ? 8 : 7;
|
||||
Assert.That(texturedPlayerMaterialCount, Is.GreaterThanOrEqualTo(expectedTexturedPlayerMaterialCount),
|
||||
"The provider bundle must retain its advertised native material textures.");
|
||||
var directionalLightIntensity = UnityEngine.Object.FindObjectsOfType<Light>()
|
||||
.Where(light => light != null && light.enabled && light.type == LightType.Directional)
|
||||
|
|
@ -1015,25 +1019,28 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
File.WriteAllBytes(mapCapturePath, pixels.EncodeToPNG());
|
||||
Assert.That(new FileInfo(mapCapturePath).Length, Is.GreaterThan(1024));
|
||||
Debug.Log($"EveUnity witness phase map-capture took {mapCaptureElapsed.Elapsed.TotalMilliseconds:0.###}ms.");
|
||||
var tractorReleaseVersion = runtime.ActiveVersion;
|
||||
var tractorRelease = host.SubmitAdvertisedActionValueIntent(
|
||||
playerId,
|
||||
beamPresentation.ActivationActionId,
|
||||
0f);
|
||||
var tractorReleaseDeadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < tractorReleaseDeadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != tractorRelease.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase) ||
|
||||
runtime.ActiveVersion < runtime.LastReceipt.SourceVersion))
|
||||
if (requireSessionGameplay)
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
var tractorReleaseVersion = runtime.ActiveVersion;
|
||||
var tractorRelease = host.SubmitAdvertisedActionValueIntent(
|
||||
playerId,
|
||||
beamPresentation.ActivationActionId,
|
||||
0f);
|
||||
var tractorReleaseDeadline = Time.realtimeSinceStartup + 12f;
|
||||
while (Time.realtimeSinceStartup < tractorReleaseDeadline &&
|
||||
(runtime.LastReceipt == null || runtime.LastReceipt.CommandId != tractorRelease.CommandId ||
|
||||
!string.Equals(runtime.LastReceipt.State, "reconciled", StringComparison.OrdinalIgnoreCase) ||
|
||||
runtime.ActiveVersion < runtime.LastReceipt.SourceVersion))
|
||||
{
|
||||
yield return new WaitForSecondsRealtime(0.1f);
|
||||
runtime.Refresh();
|
||||
}
|
||||
AssertReconciledProviderReceipt(runtime.LastReceipt, tractorRelease.CommandId,
|
||||
provider.Selection.ProviderId, provider.Selection.SurfaceId, tractorReleaseVersion);
|
||||
tractorReleaseReceipt = WitnessReceipt.From("beam-release", runtime.LastReceipt);
|
||||
beamRenderer.RefreshNow();
|
||||
Assert.That(beamRenderer.TryGetPower(beamPresentation.Id, out tractorReleasedPower), Is.True);
|
||||
}
|
||||
AssertReconciledProviderReceipt(runtime.LastReceipt, tractorRelease.CommandId,
|
||||
provider.Selection.ProviderId, provider.Selection.SurfaceId, tractorReleaseVersion);
|
||||
tractorReleaseReceipt = WitnessReceipt.From("beam-release", runtime.LastReceipt);
|
||||
beamRenderer.RefreshNow();
|
||||
Assert.That(beamRenderer.TryGetPower(beamPresentation.Id, out tractorReleasedPower), Is.True);
|
||||
var fieldVolume = root.GetComponent<EveUnityFieldsVolumeRenderer>();
|
||||
Assert.That(fieldVolume, Is.Not.Null, "The generic client did not install its Fields volume lowerer.");
|
||||
Assert.That(fieldVolume.PresentedFrameId, Is.GreaterThanOrEqualTo(0),
|
||||
|
|
|
|||
|
|
@ -4,84 +4,64 @@
|
|||
|
||||
The generic `ReleaseConsumerProject` is pinned to released Git packages:
|
||||
|
||||
- `org.gamecult.eve.unity-scene` `0.3.94`, commit
|
||||
`0463ddff4e39c9cca14e632b7e46b6b0081c67cc`, and
|
||||
- `org.gamecult.eve.unity-scene` `0.3.100`, commit
|
||||
`3632bfb3354065b78a90b921d7025c4c3fa92be4`, and
|
||||
`org.gamecult.eve.surface` `0.2.4`, commit
|
||||
`e08fa08335f99e9edddeb706912eecfad07cb281`;
|
||||
- `org.gamecult.eve.plugin-fields` `0.2.3`, commit
|
||||
`c5a4a75c1b727499b16c2dae1895f29e2a9f72f0`;
|
||||
- `org.gamecult.eve.unity-uitoolkit` `0.1.1`, commit
|
||||
`4d0cbe0185bdc4fc65eb63503a7c5cb578539669`;
|
||||
- `org.gamecult.cultlib` `1.0.34`, commit
|
||||
`c148d891c1d8713285ae15b2f17b59c106fb9426`.
|
||||
- `org.gamecult.cultlib` `1.0.43`, commit
|
||||
`f67f5122ed1bd11da016e7b820ed60145ccd0299`.
|
||||
|
||||
The hand-run integration gate is the warm released-package witness:
|
||||
The hand-run integration gates are the cold lowering proof and the warm
|
||||
full-session proof:
|
||||
|
||||
```powershell
|
||||
pwsh -File .\scripts\run-aetheria-daemon-world-witness.ps1 `
|
||||
-CacheState warm `
|
||||
-AssetCacheDirectory E:\Projects\Aetheria\Aetheria.Unity\Build\AssetCache `
|
||||
-OutputDirectory artifacts\dockyard-trade-warm-8 `
|
||||
-CultLibRoot E:\Projects\CultLib-codex-cultmesh-reliability `
|
||||
-CacheState cold `
|
||||
-AssetCacheDirectory artifacts\cultlib-1043-scene-03100-cold-cache `
|
||||
-OutputDirectory artifacts\cultlib-1043-scene-03100-cold `
|
||||
-SkipAssetBundleBuild
|
||||
```
|
||||
|
||||
It connects directly to the Aetheria daemon and must produce one passing
|
||||
PlayMode result, a pilot capture, a map-only capture, and typed witness facts.
|
||||
The current assertions require provider-owned assets, movement, camera-channel
|
||||
isolation, combat, destruction-created loot, daemon-owned XZ proximity
|
||||
collection or capacity refusal, held tractor input, and authoritative receipts.
|
||||
They do not require or accept Ymir contact identity as the owner of looting.
|
||||
The explicit prime flag rebuilds the provider bundle and installs that exact
|
||||
content-hashed body into the local warm cache. This is convenient local setup,
|
||||
not CDN-transfer evidence. On later runs, use `-SkipAssetBundleBuild` and omit
|
||||
the prime flag when neither provider assets nor their catalog changed.
|
||||
Both connect directly to the Aetheria daemon. Control, subscriptions, commands,
|
||||
and receipts use `cultnet+tcp`; provider files use `cultmesh-content+tcp`;
|
||||
same-machine entity state uses a mapped SoA body; and the released native QUIC
|
||||
client receives the advertised latest-only realtime body. No Odin hop or
|
||||
Aetheria-specific gameplay code participates in the Unity runtime.
|
||||
|
||||
The split transport proof now passes warm and cold. Control/discovery,
|
||||
subscriptions, commands, and receipts use `cultnet+tcp`; the same-machine entity
|
||||
body resolves to `SharedFileMapping`; CDN bytes use a separate
|
||||
`cultmesh-content+tcp` endpoint. The empty-cache run in
|
||||
`artifacts/aetheria-daemon-tcp-cold` began with zero bodies and zero partials,
|
||||
transferred the 56,204,750-byte provider bundle in 215 TCP content chunks,
|
||||
verified hash `f2c8acf938998703799e909cbf0c6e3ed9ad5d6f83b708a0b7b6e76ee33f7160`,
|
||||
and atomically promoted one body with no partial left behind. The cold-start
|
||||
Unity test completed in 28.4 seconds and the complete wrapper in 82.1 seconds.
|
||||
The prior path that carried bundle chunks through batched snapshot records
|
||||
timed out and remains rejected; this passing evidence belongs only to the
|
||||
dedicated TCP content plane.
|
||||
The current cold proof is
|
||||
`artifacts/cultlib-1043-scene-03100-cold5/runtime-witness.cold.json`. It began
|
||||
with no bodies or partials and passed in 57.8 seconds end to end (14.9 seconds
|
||||
inside PlayMode). The client materialized nine requested bundles totaling
|
||||
56,872,521 bytes: shaders, core resources, UI, Longinus, tractor beam, the three
|
||||
visible celestial types, and the visible asteroid. Every body matches the
|
||||
current provider file by SHA-256 and length; no partial remained. Unused ships,
|
||||
stations, shield, mine, turret, pickup, lightning, and explosion bundles stayed
|
||||
unloaded. This cold profile owns content transfer, world lowering, fog and
|
||||
Stardust execution, and pilot/map camera isolation. It deliberately issues no
|
||||
gameplay command into the paused Terminus fixture.
|
||||
|
||||
The July 19 released-package run in `artifacts/aetheria-daemon-tcp-warm` passes the
|
||||
full-session gate. The generic client lowers the provider-owned bundle through
|
||||
`SharedFileMapping`, docks at the daemon-authored 12-berth Zenith Dockyard,
|
||||
buys and sells one typed item, undocks, moves, targets, aims, runs a held tractor
|
||||
beam, destroys the sole proof hostile, and collects the resulting loot exactly
|
||||
once through daemon-owned proximity. All eight retained witness receipts are
|
||||
provider-owned and reconciled. The run records 65,536 Stardust particles, 396
|
||||
field composites/dispatches/draws, and both camera-channel invariants. The pilot
|
||||
capture contains the 3D fog/Stardust/ship frame and no map icons; the map capture
|
||||
contains the map icons against its map background. The pilot image remains
|
||||
visually overexposed and is integration evidence, not final art approval.
|
||||
The wrapper starts the client before the daemon so package import time does not
|
||||
advance the live proof world. EveUnity 0.3.94 reports a refused TCP rendezvous as
|
||||
a retryable provider-preparation failure; once the daemon binds, the same generic
|
||||
preparation path connects without an Aetheria-specific reconnect shim.
|
||||
The current warm full-session proof is
|
||||
`artifacts/cultlib-1043-scene-03100-warm/runtime-witness.warm.json`. It passed in
|
||||
70.7 seconds end to end (27.9 seconds inside PlayMode). The generic client docks,
|
||||
buys and sells one typed item, resumes and undocks, moves, targets, aims, holds
|
||||
and releases the tractor beam, destroys the proof hostile, and collects the
|
||||
resulting loot exactly once through daemon-owned XZ proximity. All eight
|
||||
retained receipts are provider-owned and reconciled. Eleven on-demand bundles
|
||||
totaling 74,191,724 bytes were present by the end; gameplay loaded only the
|
||||
additional content it exercised. The pilot camera excludes all eleven map
|
||||
renderers and the map camera includes them.
|
||||
|
||||
The July 19 transport-boundary run in `artifacts/demanded-fields-warm-6`
|
||||
passed its released-consumer PlayMode test and produced both camera captures.
|
||||
The provider published the requested Fields viewport only after CultMesh
|
||||
observed the client's exact record/schema demand. Entity state used the
|
||||
same-machine mapped SoA body, while the one-second Eve surface remained a
|
||||
separate reactive control/presentation stream. The facts record 65,536
|
||||
Stardust particles, 145 field composites and draws, pilot/map camera isolation,
|
||||
movement, combat, exactly-once destruction-loot collection, tractor activation,
|
||||
and a reconciled held-input release. Terminus attention had paused simulation,
|
||||
so the released target latch coexists honestly with frozen ramped beam power
|
||||
`0.84`; the generic client does not manufacture a visual zero.
|
||||
|
||||
The wrapper currently rejects this otherwise passing run after Unity exits
|
||||
because its full-session gate requires docked purchase/sale fields that the
|
||||
generic capture test does not yet emit. Consequently this run is transport and
|
||||
gameplay evidence, not a completed full-session readiness witness, and no
|
||||
`runtime-witness.json` was issued.
|
||||
The pilot capture proves that provider fog, Stardust, celestial meshes, and ship
|
||||
meshes reach URP, but it is not final visual approval: hulls remain crushed to
|
||||
black and the cloud frame remains too hot and cyan-grey. Those are provider
|
||||
visual-lever and shader-calibration issues, not concealed transport failures.
|
||||
The map capture is clean and contains only map-channel glyphs on its dark map
|
||||
background.
|
||||
|
||||
## Historical witness ledger
|
||||
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ param(
|
|||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$expectedEveUnityCommit = "91eaa95ad45897f4322a8823a1bc5cddcee59649"
|
||||
$expectedEveUnityCommit = "3632bfb3354065b78a90b921d7025c4c3fa92be4"
|
||||
$expectedEveFieldsCommit = "c5a4a75c1b727499b16c2dae1895f29e2a9f72f0"
|
||||
$expectedEveUnityUiToolkitCommit = "4d0cbe0185bdc4fc65eb63503a7c5cb578539669"
|
||||
$expectedCultLibCommit = "54e2e69ff7f4f5e0a1316bb047c315e65ed2a185"
|
||||
$expectedCultLibCommit = "f67f5122ed1bd11da016e7b820ed60145ccd0299"
|
||||
$repoRoot = Split-Path -Parent $PSScriptRoot
|
||||
$projectRoot = $ClientProject
|
||||
$outputRoot = if ([IO.Path]::IsPathRooted($OutputDirectory)) { $OutputDirectory } else { Join-Path $repoRoot $OutputDirectory }
|
||||
|
|
@ -140,13 +140,15 @@ if (-not $SkipAssetBundleBuild) {
|
|||
throw "Aetheria AssetBundle build failed with exit code $($bundleBuilder.ExitCode)"
|
||||
}
|
||||
}
|
||||
$providerBundlePaths = @(Get-ChildItem -LiteralPath $providerBundleDirectory -Filter "aetheria-*" -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Extension -ne ".manifest" } | Select-Object -ExpandProperty FullName)
|
||||
if ($providerBundlePaths.Count -eq 0) {
|
||||
throw "Provider-owned Aetheria bundles are missing: $providerBundleDirectory"
|
||||
}
|
||||
if ($PrimeWarmCacheFromProviderBundle) {
|
||||
if ($CacheState -ne "warm") {
|
||||
throw "Local provider-bundle priming is only valid for an explicitly warm witness."
|
||||
}
|
||||
$providerBundlePaths = @(Get-ChildItem -LiteralPath $providerBundleDirectory -Filter "aetheria-*" -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Extension -ne ".manifest" } | Select-Object -ExpandProperty FullName)
|
||||
if ($providerBundlePaths.Count -eq 0) { throw "Provider-owned Aetheria bundles are missing: $providerBundleDirectory" }
|
||||
New-Item -ItemType Directory -Force -Path $assetCachePath | Out-Null
|
||||
foreach ($providerBundlePath in $providerBundlePaths) {
|
||||
$primeHash = (Get-FileHash -LiteralPath $providerBundlePath -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
|
|
@ -164,16 +166,9 @@ if ($PrimeWarmCacheFromProviderBundle) {
|
|||
Write-Host "Warm cache primed locally from $($providerBundlePaths.Count) provider bundles; this is not CDN-transfer evidence: $assetCachePath"
|
||||
}
|
||||
if ($CacheState -eq "warm") {
|
||||
$providerBundlePaths = @(Get-ChildItem -LiteralPath $providerBundleDirectory -Filter "aetheria-*" -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Extension -ne ".manifest" } | Select-Object -ExpandProperty FullName)
|
||||
if ($providerBundlePaths.Count -eq 0) { throw "Provider-owned Aetheria bundles are missing: $providerBundleDirectory" }
|
||||
foreach ($providerBundlePath in $providerBundlePaths) {
|
||||
$currentBundleHash = (Get-FileHash -LiteralPath $providerBundlePath -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
$currentWarmBody = Get-ChildItem -LiteralPath $assetCachePath -Filter "$currentBundleHash.body" -File -Recurse -ErrorAction SilentlyContinue |
|
||||
Select-Object -First 1
|
||||
if ($null -eq $currentWarmBody) {
|
||||
throw "Warm witness cache does not contain current provider bundle '$providerBundlePath'. expected=$currentBundleHash cache=$assetCachePath"
|
||||
}
|
||||
$currentWarmBodies = @(Get-ChildItem -LiteralPath $assetCachePath -Filter *.body -File -Recurse -ErrorAction SilentlyContinue)
|
||||
if ($currentWarmBodies.Count -eq 0) {
|
||||
throw "Warm witness cache contains no promoted provider bodies: $assetCachePath"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -283,14 +278,14 @@ try {
|
|||
throw "Live witness ran the wrong proof profile. expected=$witnessProfile actual=$($facts.witnessProfile)"
|
||||
}
|
||||
if (-not $facts.providerAssets -or -not $facts.environmentPresentation -or
|
||||
-not $facts.movement -or -not $facts.pilotCameraExcludesMapChannel -or
|
||||
-not $facts.pilotCameraExcludesMapChannel -or
|
||||
-not $facts.mapCameraIncludesMapChannel -or [int]$facts.fieldVolumeLayerCount -le 0 -or
|
||||
[long]$facts.fieldVolumeCompositeCount -le 0 -or
|
||||
[int]$facts.fieldParticleCount -ne 65536 -or
|
||||
[int]$facts.fieldParticleDispatchCount -le 0 -or
|
||||
[int]$facts.fieldParticleDrawCount -le 0 -or
|
||||
-not $facts.fieldParticleMapCameraIsolated) {
|
||||
throw "Live witness did not prove provider assets, movement, Fields lowering, Stardust dispatch/draw, and camera-channel separation."
|
||||
throw "Live witness did not prove provider assets, Fields lowering, Stardust dispatch/draw, and camera-channel separation."
|
||||
}
|
||||
$gridCenterXCells = [double]$facts.fieldParticleGridCenter.x / 6.0
|
||||
$gridCenterYCells = [double]$facts.fieldParticleGridCenter.y / 6.0
|
||||
|
|
@ -314,6 +309,9 @@ try {
|
|||
throw "Live witness did not prove provider-owned celestial bodies and asteroids reached the generic scene and intersected the pilot frustum. bodies=$($presentedBodies.Count) asteroids=$($presentedAsteroids.Count) invalid=$($invalidCelestials.Count)"
|
||||
}
|
||||
if ($witnessProfile -eq "full-session-gameplay") {
|
||||
if (-not $facts.movement) {
|
||||
throw "Full-session witness did not prove authoritative movement and its receipt."
|
||||
}
|
||||
if (-not $facts.tradeRoundTrip -or [string]::IsNullOrWhiteSpace($facts.tradeItemKey)) {
|
||||
throw "Full-session witness did not prove docked purchase and sale through provider-advertised generic actions."
|
||||
}
|
||||
|
|
@ -351,17 +349,37 @@ try {
|
|||
}
|
||||
$finalBodies = @(Get-ChildItem -LiteralPath $assetCachePath -Filter *.body -File -Recurse -ErrorAction SilentlyContinue)
|
||||
$finalPartials = @(Get-ChildItem -LiteralPath $assetCachePath -Filter *.partial -File -Recurse -ErrorAction SilentlyContinue)
|
||||
if (-not (Test-Path -LiteralPath $providerBundlePath)) {
|
||||
throw "Provider-owned Aetheria bundle is missing: $providerBundlePath"
|
||||
if ($finalPartials.Count -ne 0) {
|
||||
throw "Provider bundle promotion left partial bodies behind. bodies=$($finalBodies.Count) partials=$($finalPartials.Count)"
|
||||
}
|
||||
$bodyHash = (Get-FileHash -LiteralPath $providerBundlePath -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
$promotedBundleBodies = @($finalBodies | Where-Object { $_.BaseName -eq $bodyHash })
|
||||
if ($promotedBundleBodies.Count -ne 1 -or $finalPartials.Count -ne 0) {
|
||||
throw "Provider bundle promotion is incomplete. matchingBodies=$($promotedBundleBodies.Count) bodies=$($finalBodies.Count) partials=$($finalPartials.Count) hash=$bodyHash"
|
||||
$providerBundlesByHash = @{}
|
||||
foreach ($providerBundlePath in $providerBundlePaths) {
|
||||
$providerBundle = Get-Item -LiteralPath $providerBundlePath
|
||||
$bodyHash = (Get-FileHash -LiteralPath $providerBundle.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
$providerBundlesByHash[$bodyHash] = $providerBundle
|
||||
}
|
||||
$promotedBodyHash = (Get-FileHash -LiteralPath $promotedBundleBodies[0].FullName -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
if ($promotedBodyHash -ne $bodyHash -or $promotedBundleBodies[0].Length -ne (Get-Item -LiteralPath $providerBundlePath).Length) {
|
||||
throw "Promoted provider bundle does not match its authoritative body. expected=$bodyHash actual=$promotedBodyHash"
|
||||
$contentArtifacts = @()
|
||||
foreach ($body in $finalBodies) {
|
||||
$bodyHash = $body.BaseName.ToLowerInvariant()
|
||||
if (-not $providerBundlesByHash.ContainsKey($bodyHash)) {
|
||||
throw "Asset cache contains a body not owned by the current Aetheria bundle set. body=$($body.FullName) hash=$bodyHash"
|
||||
}
|
||||
$providerBundle = $providerBundlesByHash[$bodyHash]
|
||||
$promotedBodyHash = (Get-FileHash -LiteralPath $body.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
if ($promotedBodyHash -ne $bodyHash -or $body.Length -ne $providerBundle.Length) {
|
||||
throw "Promoted provider bundle does not match its authoritative body. bundle=$($providerBundle.Name) expected=$bodyHash actual=$promotedBodyHash"
|
||||
}
|
||||
$contentArtifacts += [pscustomobject][ordered]@{
|
||||
name = $providerBundle.Name
|
||||
contentHash = $bodyHash
|
||||
sizeBytes = $providerBundle.Length
|
||||
}
|
||||
}
|
||||
$requiredFoundationBundles = @('aetheria-shaders', 'aetheria-core', 'aetheria-ui')
|
||||
$promotedBundleNames = @($contentArtifacts | ForEach-Object { $_.name })
|
||||
$missingFoundationBundles = @($requiredFoundationBundles | Where-Object { $_ -notin $promotedBundleNames })
|
||||
if ($missingFoundationBundles.Count -ne 0) {
|
||||
throw "The generic client did not materialize every provider foundation bundle. missing=[$($missingFoundationBundles -join ',')] promoted=[$($promotedBundleNames -join ',')]"
|
||||
}
|
||||
$facts | Add-Member -NotePropertyName releasedPackageClient -NotePropertyValue $releasedPackageClient
|
||||
$facts | Add-Member -NotePropertyName clientProject -NotePropertyValue $projectRoot
|
||||
|
|
@ -374,8 +392,9 @@ try {
|
|||
initialPartialCount = $initialPartialCount
|
||||
finalBodyCount = $finalBodies.Count
|
||||
finalPartialCount = $finalPartials.Count
|
||||
contentHash = $bodyHash
|
||||
sizeBytes = $promotedBundleBodies[0].Length
|
||||
bundleCount = $contentArtifacts.Count
|
||||
sizeBytes = ($contentArtifacts | Measure-Object -Property sizeBytes -Sum).Sum
|
||||
artifacts = $contentArtifacts
|
||||
})
|
||||
$capture = Get-Item -LiteralPath $capturePath
|
||||
$mapCapture = Get-Item -LiteralPath $mapCapturePath
|
||||
|
|
|
|||
Reference in a new issue