From 028042009ef41063fe61c1d8a62167e04b00e143 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Thu, 9 Jul 2026 19:59:52 +0100 Subject: [PATCH] Add generic EveUnity playable client bootstrap --- docs/eve-migration-roadmap.md | 19 +- .../EveUnityPlayableWorldClientBootstrap.cs | 192 ++++++++++++++++++ ...eUnityPlayableWorldClientBootstrap.cs.meta | 11 + .../EveUnityPlayableWorldClientHost.cs | 8 +- .../EveUnitySceneSurfaceLowererTests.cs | 55 +++++ .../eve-runtime-capability.json | 4 + .../eveunity-scene-split-handoff.json | 19 +- scripts/run-aetheria-unity-package-smoke.ps1 | 26 +++ ...un-eveunity-scene-provider-shell-smoke.ps1 | 15 +- ...ntime-owner-conformance-consumer-smoke.ps1 | 4 + ...plit-target-conformance-consumer-smoke.ps1 | 2 + tools/parity/parity-manifest.json | 30 ++- 12 files changed, 372 insertions(+), 13 deletions(-) create mode 100644 runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs create mode 100644 runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs.meta diff --git a/docs/eve-migration-roadmap.md b/docs/eve-migration-roadmap.md index 275c70d..c65d38f 100644 --- a/docs/eve-migration-roadmap.md +++ b/docs/eve-migration-roadmap.md @@ -649,12 +649,19 @@ Recently cut: manifest document loading boundary and feed that cache without importing Aetheria asset classes. `EveUnityLivePlayableWorldAssetProvider` connects that cache to the active world pointer for GameObject scenes. The Unity - client boundary is generic before it learns - live transport. The next blocker is the live generic Unity player loop: - implement the CultMesh/CultNet adapter, implement concrete CultMesh/CultCache - readers for provider surface and asset manifest documents, and prove - provider receipts plus daemon snapshots drive rendered Unity frames rather - than renderer-local simulation. + client boundary is generic before it learns live transport. + `EveUnityPlayableWorldClientHost`, + `EveUnityPlayableWorldClientBootstrap`, + `EveUnityPlayableWorldInputDriver`, and `EveUnityPlayableWorldCameraRig` now + form the first generic Unity client body: a provider component that implements + the Eve interfaces can be mounted without Aetheria-specific client code, + provider-authored entities are instantiated under a Unity scene root, camera + and movement input are runtime-owned, and movement exits through the + provider-advertised `gamecult.eve.command.v1` boundary. The next blocker is + owner-repo live proof: implement the CultMesh/CultNet adapter, implement + concrete CultMesh/CultCache readers for provider surface and asset manifest + documents, and prove provider receipts plus daemon snapshots drive rendered + Unity frames rather than renderer-local simulation. - EveElectron capture lifecycle now carries the same kind of structured pending capture contract. `captureContract` names the Electron shell runtime, capture kind, PNG artifact pattern, conformance attachment point, required Aetheria diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs new file mode 100644 index 0000000..e46c410 --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs @@ -0,0 +1,192 @@ +using System; +using UnityEngine; + +#nullable enable + +namespace GameCult.Eve.UnityScene +{ + public sealed class EveUnityPlayableWorldClientBootstrap : MonoBehaviour + { + [SerializeField] private EveUnityPlayableWorldClientHost? host; + [SerializeField] private MonoBehaviour? provider; + [SerializeField] private MonoBehaviour? providerSurfaceDocuments; + [SerializeField] private MonoBehaviour? commandSink; + [SerializeField] private MonoBehaviour? assetManifestDocuments; + [SerializeField] private MonoBehaviour? receiptSource; + [SerializeField] private MonoBehaviour? fallbackAssetProvider; + [SerializeField] private Transform? sceneRoot; + [SerializeField] private Transform? cameraTransform; + [SerializeField] private bool createSceneRootIfMissing = true; + [SerializeField] private bool attachInputDriver = true; + [SerializeField] private bool attachCameraRig = true; + [SerializeField] private bool connectOnEnable = true; + + public EveUnityPlayableWorldClientHost? Host => host; + + public Transform? SceneRoot => sceneRoot; + + public Transform? CameraTransform => cameraTransform; + + public EveUnityPlayableWorldPresentation? LastPresentation { get; private set; } + + public void ConfigureProvider(MonoBehaviour providerComponent) + { + provider = providerComponent != null ? providerComponent : throw new ArgumentNullException(nameof(providerComponent)); + providerSurfaceDocuments = provider; + commandSink = provider; + assetManifestDocuments = provider; + receiptSource = provider; + } + + public EveUnityPlayableWorldPresentation Mount() + { + var resolvedHost = ResolveHost(); + var resolvedProvider = provider; + var surfaceDocuments = ResolveBehaviour( + providerSurfaceDocuments, + resolvedProvider, + nameof(providerSurfaceDocuments)); + var resolvedCommandSink = ResolveBehaviour( + commandSink, + resolvedProvider, + nameof(commandSink)); + var resolvedAssetDocuments = ResolveOptionalBehaviour( + assetManifestDocuments, + resolvedProvider); + var resolvedReceiptSource = ResolveOptionalBehaviour( + receiptSource, + resolvedProvider); + var resolvedFallbackAssetProvider = ResolveOptionalBehaviour( + fallbackAssetProvider, + null); + + sceneRoot = ResolveSceneRoot(); + resolvedHost.ConnectOnEnable = false; + resolvedHost.Configure( + sceneRoot, + surfaceDocuments, + resolvedCommandSink, + resolvedAssetDocuments, + resolvedReceiptSource, + resolvedFallbackAssetProvider); + + if (attachInputDriver) + ConfigureInputDriver(resolvedHost); + + if (attachCameraRig) + ConfigureCameraRig(resolvedHost); + + LastPresentation = resolvedHost.Connect(); + return LastPresentation; + } + + private void Awake() + { + if (host != null && provider != null) + host.ConnectOnEnable = false; + } + + private void OnEnable() + { + if (connectOnEnable) + Mount(); + } + + private EveUnityPlayableWorldClientHost ResolveHost() + { + if (host != null) + return host; + + host = GetComponent(); + if (host == null) + host = gameObject.AddComponent(); + + return host; + } + + private Transform ResolveSceneRoot() + { + if (sceneRoot != null) + return sceneRoot; + + if (!createSceneRootIfMissing) + return transform; + + var root = new GameObject("Eve Unity Playable World Root"); + root.transform.SetParent(transform, false); + sceneRoot = root.transform; + return sceneRoot; + } + + private Transform ResolveCameraTransform() + { + if (cameraTransform != null) + return cameraTransform; + + var mainCamera = Camera.main; + if (mainCamera != null) + { + cameraTransform = mainCamera.transform; + return cameraTransform; + } + + var cameraObject = new GameObject("Eve Unity Playable World Camera"); + cameraObject.AddComponent(); + cameraTransform = cameraObject.transform; + return cameraTransform; + } + + private void ConfigureInputDriver(EveUnityPlayableWorldClientHost resolvedHost) + { + var driver = GetComponent(); + if (driver == null) + driver = gameObject.AddComponent(); + + driver.Host = resolvedHost; + driver.CameraTransform = ResolveCameraTransform(); + } + + private void ConfigureCameraRig(EveUnityPlayableWorldClientHost resolvedHost) + { + var rig = GetComponent(); + if (rig == null) + rig = gameObject.AddComponent(); + + rig.Host = resolvedHost; + rig.CameraTransform = ResolveCameraTransform(); + } + + private MonoBehaviour ResolveBehaviour( + MonoBehaviour? explicitComponent, + MonoBehaviour? providerComponent, + string fieldName) where T : class + { + var resolved = ResolveOptionalBehaviour(explicitComponent, providerComponent); + if (resolved != null) + return resolved; + + throw new InvalidOperationException( + $"Eve Unity playable world bootstrap requires '{fieldName}' or provider to implement {typeof(T).Name}."); + } + + private MonoBehaviour? ResolveOptionalBehaviour( + MonoBehaviour? explicitComponent, + MonoBehaviour? providerComponent) where T : class + { + if (explicitComponent is T) + return explicitComponent; + + if (providerComponent is T) + return providerComponent; + + var components = GetComponents(); + foreach (var component in components) + { + if (component is T) + return component; + } + + return null; + } + } +} diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs.meta b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs.meta new file mode 100644 index 0000000..845b68c --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d5e4b8e1e104bb99522dc2b75d7f4c9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs index da45718..c57f633 100644 --- a/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs @@ -14,7 +14,7 @@ namespace GameCult.Eve.UnityScene [SerializeField] private MonoBehaviour? assetManifestDocuments; [SerializeField] private MonoBehaviour? receiptSource; [SerializeField] private MonoBehaviour? fallbackAssetProvider; - [SerializeField] private bool connectOnEnable = true; + [SerializeField] private bool connectOnEnable; [SerializeField] private bool refreshInUpdate = true; [SerializeField] private float refreshIntervalSeconds = 0.1f; @@ -34,6 +34,12 @@ namespace GameCult.Eve.UnityScene public Transform SceneRoot => sceneRoot == null ? transform : sceneRoot; + public bool ConnectOnEnable + { + get => connectOnEnable; + set => connectOnEnable = value; + } + public void Configure( Transform? sceneRoot, MonoBehaviour providerSurfaceDocuments, diff --git a/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs b/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs index cd67f82..22aae62 100644 --- a/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs +++ b/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs @@ -400,6 +400,61 @@ namespace GameCult.Eve.UnityScene.Tests } } + [Test] + public void PlayableWorldClientBootstrapWiresGenericUnityClientFromProviderInterfaces() + { + var hostObject = new GameObject("generic-eve-client"); + hostObject.SetActive(false); + + try + { + var provider = hostObject.AddComponent(); + provider.Set( + new EveUnitySceneProviderSurfaceDocument( + PlayableArpgDocument(), + Advertisement("aetheria.daemon.game"), + "cultmesh://aetheria/eve/surfaces/aetheria.daemon.game", + 1), + new EveUnityPlayableWorldAssetManifestDocument( + "cultmesh://aetheria/assets/manifest", + Array.Empty(), + "aetheria")); + + var bootstrap = hostObject.AddComponent(); + bootstrap.ConfigureProvider(provider); + + hostObject.SetActive(true); + + Assert.That(bootstrap.Host, Is.Not.Null); + Assert.That(bootstrap.Host!.ActiveWorld, Is.Not.Null); + Assert.That(bootstrap.Host.ActiveWorld!.PlayerEntityId, Is.EqualTo("player-vanguard")); + Assert.That(bootstrap.LastPresentation, Is.Not.Null); + Assert.That(bootstrap.LastPresentation!.ActiveEntities, Is.EqualTo(3)); + Assert.That(bootstrap.SceneRoot, Is.Not.Null); + Assert.That(bootstrap.SceneRoot!.childCount, Is.EqualTo(3)); + Assert.That(hostObject.GetComponent(), Is.Not.Null); + Assert.That(hostObject.GetComponent(), Is.Not.Null); + Assert.That(bootstrap.CameraTransform, Is.Not.Null); + Assert.That(provider.RefreshCount, Is.EqualTo(1)); + + var input = hostObject.GetComponent(); + var moveVector = input.SubmitMoveVectorInput(0f, 1f); + + Assert.That(moveVector, Is.Not.Null); + Assert.That(provider.Submitted.Count, Is.EqualTo(1)); + Assert.That(provider.Submitted[0], Is.SameAs(moveVector)); + Assert.That(moveVector!.ProviderId, Is.EqualTo("aetheria")); + Assert.That(moveVector.SurfaceId, Is.EqualTo("aetheria.daemon.game")); + Assert.That(moveVector.CommandBoundary, Is.EqualTo("aetheria.daemon.commands")); + Assert.That(moveVector.Payload.GetString("commandId"), Is.EqualTo("aetheria.daemon.move_intent")); + Assert.That(moveVector.Payload.GetString("entityId"), Is.EqualTo("player-vanguard")); + } + finally + { + UnityEngine.Object.DestroyImmediate(hostObject); + } + } + [Test] public void PlayableWorldClientHostSubmitsProviderOwnedMoveVector() { diff --git a/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json b/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json index 2623c80..78e9bde 100644 --- a/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json +++ b/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json @@ -23,6 +23,7 @@ "providerCommandReceipts", "providerAssetManifestDocumentSource", "playableWorldClientHost", + "playableWorldClientBootstrap", "playableWorldInputDriver", "playableWorldCameraRig", "sceneGraphProjection", @@ -78,6 +79,7 @@ "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldLiveClient.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldInputDriver.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldCameraRig.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityProviderRefreshSource.cs", @@ -135,6 +137,7 @@ "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldLiveClient.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldInputDriver.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldCameraRig.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityProviderRefreshSource.cs", @@ -181,6 +184,7 @@ "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldLiveClient.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldInputDriver.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldCameraRig.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityProviderRefreshSource.cs", diff --git a/runtimes/incubating/eve-unity-scene/eveunity-scene-split-handoff.json b/runtimes/incubating/eve-unity-scene/eveunity-scene-split-handoff.json index 4d02375..5088528 100644 --- a/runtimes/incubating/eve-unity-scene/eveunity-scene-split-handoff.json +++ b/runtimes/incubating/eve-unity-scene/eveunity-scene-split-handoff.json @@ -20,6 +20,10 @@ "runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldLiveClient.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldInputDriver.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldCameraRig.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldPresenter.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityGameObjectPlayableWorldSceneSink.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldAssetManifest.cs", @@ -43,6 +47,10 @@ "runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldLiveClient.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldInputDriver.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldCameraRig.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldPresenter.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityGameObjectPlayableWorldSceneSink.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldAssetManifest.cs", @@ -66,6 +74,10 @@ "runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldLiveClient.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldInputDriver.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldCameraRig.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldPresenter.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityGameObjectPlayableWorldSceneSink.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldAssetManifest.cs", @@ -76,7 +88,7 @@ "runtimes/incubating/eve-unity-scene/eve-runtime-capability.json" ], "destinationOwner": "EveUnity", - "replacementProof": "EveUnity claims the provider-advertised unity-scene lowering target with provider-agnostic playable-world projection, scene graph projection, typed provider surface document loading, provider snapshot session, a playable-world runtime host, live playable-world client composition, provider command receipt observation, playable-world scene presentation, Unity GameObject scene sink, typed provider asset manifest document loading, provider asset manifest resolution, provider asset manifest source/cache, and command boundary evidence; live transport and capture remain separate lifecycle proofs." + "replacementProof": "EveUnity claims the provider-advertised unity-scene lowering target with provider-agnostic playable-world projection, scene graph projection, typed provider surface document loading, provider snapshot session, a playable-world runtime host, generic client bootstrap, movement input driver, camera rig, live playable-world client composition, provider command receipt observation, playable-world scene presentation, Unity GameObject scene sink, typed provider asset manifest document loading, provider asset manifest resolution, provider asset manifest source/cache, and command boundary evidence; live transport and capture remain separate lifecycle proofs." }, { "id": "unity-scene-sai-plugin-projection", @@ -121,6 +133,9 @@ "runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneSurfaceLowerer.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneClientSession.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldInputDriver.cs", "runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs", "runtimes/incubating/eve-unity-scene/eve-runtime-capability.json" ], @@ -166,6 +181,8 @@ "EveUnity owns a provider-snapshot Unity scene client session that lowers Aetheria's surface and emits command intents without importing Aetheria project code.", "EveUnity owns typed provider surface document, provider surface source, and command sink ports that a live CultMesh/CultNet adapter can implement without changing scene lowering.", "EveUnity owns a live playable-world client coordinator that applies provider snapshots through the presenter, observes provider command receipts, and emits command intents through the advertised provider command sink without local simulation.", + "EveUnity owns a generic Unity client bootstrap that wires provider surface documents, command sink, asset manifest, input driver, camera rig, and scene root without importing provider internals.", + "EveUnity owns generic playable-world movement input and camera rig components that emit provider-owned command intents and follow provider-advertised player entities without importing provider internals.", "EveUnity owns a playable-world presenter that maps provider-authored entity rows and asset refs into Unity scene operations without importing Aetheria entity or prefab classes.", "EveUnity owns a generic Unity GameObject scene sink and asset-provider hook for playable-world rows without importing Aetheria entity or prefab classes.", "EveUnity owns gamecult.eve.unity_playable_world_asset_manifest.v1 document loading into its asset manifest cache without importing Aetheria asset classes.", diff --git a/scripts/run-aetheria-unity-package-smoke.ps1 b/scripts/run-aetheria-unity-package-smoke.ps1 index 14e8e70..860de3d 100644 --- a/scripts/run-aetheria-unity-package-smoke.ps1 +++ b/scripts/run-aetheria-unity-package-smoke.ps1 @@ -11,6 +11,7 @@ if (-not (Test-Path $AetheriaRoot)) { $manifestPath = Join-Path $AetheriaRoot "Packages\manifest.json" $unityToolkitProject = Join-Path $AetheriaRoot "GameCult.Eve.UnityUIToolkit.csproj" +$unitySceneProject = Join-Path $AetheriaRoot "GameCult.Eve.UnityScene.csproj" $surfaceProject = Join-Path $AetheriaRoot "GameCult.Eve.Surface.csproj" $aetheriaEveRuntimePackage = Join-Path $AetheriaRoot "Packages\org.gamecult.aetheria.eve-runtime\package.json" $aetheriaEveRuntimeAsmdef = Join-Path $AetheriaRoot "Packages\org.gamecult.aetheria.eve-runtime\Runtime\GameCult.Aetheria.EveRuntime.asmdef" @@ -24,6 +25,9 @@ if (-not (Test-Path $manifestPath)) { if (-not (Test-Path $unityToolkitProject)) { throw "Aetheria Unity Toolkit project not found: $unityToolkitProject" } +if (-not (Test-Path $unitySceneProject)) { + throw "Aetheria Unity Scene project not found: $unitySceneProject" +} if (-not (Test-Path $surfaceProject)) { throw "Aetheria Eve Surface project not found: $surfaceProject" } @@ -73,6 +77,27 @@ foreach ($compileItem in $requiredCompileItems) { } } +$sceneProject = Get-Content -Raw -LiteralPath $unitySceneProject +$requiredSceneCompileItems = @( + "Runtime\EveUnitySceneSurfaceLowerer.cs", + "Runtime\EveUnitySceneClientSession.cs", + "Runtime\EveUnitySceneProviderConnection.cs", + "Runtime\EveUnityPlayableWorldLiveClient.cs", + "Runtime\EveUnityPlayableWorldRuntime.cs", + "Runtime\EveUnityPlayableWorldClientHost.cs", + "Runtime\EveUnityPlayableWorldClientBootstrap.cs", + "Runtime\EveUnityPlayableWorldInputDriver.cs", + "Runtime\EveUnityPlayableWorldCameraRig.cs", + "Runtime\EveUnityGameObjectPlayableWorldSceneSink.cs", + "Runtime\EveUnityPlayableWorldAssetManifest.cs" +) +foreach ($compileItem in $requiredSceneCompileItems) { + $expected = Join-Path $eveRoot "runtimes\incubating\eve-unity-scene\$compileItem" + if (-not $sceneProject.Contains($expected)) { + throw "Aetheria GameCult.Eve.UnityScene.csproj missing compile item: $expected" + } +} + $runtimePackage = Get-Content -Raw -LiteralPath $aetheriaEveRuntimePackage foreach ($dependency in @( '"org.gamecult.eve.unity-scene": "0.1.0"', @@ -173,6 +198,7 @@ foreach ($symbol in @( Push-Location $AetheriaRoot try { dotnet build GameCult.Eve.UnityUIToolkit.csproj --no-restore --nologo -v:minimal + dotnet build GameCult.Eve.UnityScene.csproj --no-restore --nologo -v:minimal } finally { Pop-Location } diff --git a/scripts/run-eveunity-scene-provider-shell-smoke.ps1 b/scripts/run-eveunity-scene-provider-shell-smoke.ps1 index 31de4f0..fb95248 100644 --- a/scripts/run-eveunity-scene-provider-shell-smoke.ps1 +++ b/scripts/run-eveunity-scene-provider-shell-smoke.ps1 @@ -54,7 +54,7 @@ foreach ($evidencePath in @($worldSurfaceLoweringClaim.evidencePaths)) { } } -foreach ($feature in @("providerAdvertisements", "commandTransport", "providerSurfaceSession", "providerSurfaceSource", "providerSurfaceDocumentSource", "livePlayableWorldClient", "providerCommandReceipts", "providerAssetManifestDocumentSource", "playableWorldClientHost", "playableWorldInputDriver", "playableWorldCameraRig", "sceneGraphProjection", "playableWorldProjection", "playableWorldRuntimeHost", "playableWorldScenePresentation", "unityGameObjectSceneSink", "providerAssetManifestResolution", "providerAssetManifestSource")) { +foreach ($feature in @("providerAdvertisements", "commandTransport", "providerSurfaceSession", "providerSurfaceSource", "providerSurfaceDocumentSource", "livePlayableWorldClient", "providerCommandReceipts", "providerAssetManifestDocumentSource", "playableWorldClientHost", "playableWorldClientBootstrap", "playableWorldInputDriver", "playableWorldCameraRig", "sceneGraphProjection", "playableWorldProjection", "playableWorldRuntimeHost", "playableWorldScenePresentation", "unityGameObjectSceneSink", "providerAssetManifestResolution", "providerAssetManifestSource")) { if (-not (@($manifest.supportedFeatures) -contains $feature)) { throw "EveUnity scene provider shell missing supported feature: $feature" } @@ -69,6 +69,7 @@ $expectedFiles = @( "runtimes\incubating\eve-unity-scene\Runtime\EveUnityPlayableWorldLiveClient.cs", "runtimes\incubating\eve-unity-scene\Runtime\EveUnityPlayableWorldRuntime.cs", "runtimes\incubating\eve-unity-scene\Runtime\EveUnityPlayableWorldClientHost.cs", + "runtimes\incubating\eve-unity-scene\Runtime\EveUnityPlayableWorldClientBootstrap.cs", "runtimes\incubating\eve-unity-scene\Runtime\EveUnityPlayableWorldInputDriver.cs", "runtimes\incubating\eve-unity-scene\Runtime\EveUnityPlayableWorldCameraRig.cs", "runtimes\incubating\eve-unity-scene\Runtime\EveUnityProviderRefreshSource.cs", @@ -134,6 +135,16 @@ if ($clientHostSource.Contains("Aetheria")) { throw "EveUnity playable world client host must remain provider-agnostic and cannot reference Aetheria" } +$clientBootstrapSource = Get-Content -LiteralPath (Join-Path $projectRoot "runtimes\incubating\eve-unity-scene\Runtime\EveUnityPlayableWorldClientBootstrap.cs") -Raw +foreach ($symbol in @("EveUnityPlayableWorldClientBootstrap", "ConfigureProvider", "Mount", "ResolveHost", "ResolveSceneRoot", "ResolveCameraTransform", "EveUnityPlayableWorldClientHost", "EveUnityPlayableWorldInputDriver", "EveUnityPlayableWorldCameraRig", "IEveUnitySceneProviderSurfaceDocumentSource", "IEveUnitySceneCommandSink", "IEveUnityPlayableWorldAssetManifestDocumentSource", "IEveUnitySceneCommandReceiptSource", "IEveUnityGameObjectAssetProvider")) { + if (-not $clientBootstrapSource.Contains($symbol)) { + throw "EveUnity playable world client bootstrap missing symbol: $symbol" + } +} +if ($clientBootstrapSource.Contains("Aetheria")) { + throw "EveUnity playable world client bootstrap must remain provider-agnostic and cannot reference Aetheria" +} + $refreshSource = Get-Content -LiteralPath (Join-Path $projectRoot "runtimes\incubating\eve-unity-scene\Runtime\EveUnityProviderRefreshSource.cs") -Raw foreach ($symbol in @("IEveUnityProviderRefreshSource", "Refresh")) { if (-not $refreshSource.Contains($symbol)) { @@ -204,7 +215,7 @@ foreach ($symbol in @("TeXMathUnitySceneProjectionAdapter", "tex.math", "embed.t } $testSource = Get-Content -LiteralPath (Join-Path $projectRoot "runtimes\incubating\eve-unity-scene\Tests\Editor\EveUnitySceneSurfaceLowererTests.cs") -Raw -foreach ($symbol in @("LowerCarriesProviderAdvertisedWorldBoundary", "LowerBuildsProviderAgnosticSceneGraphFromSurfaceTree", "LowerExtractsPlayableArpgWorldFromGenericScene3dSurface", "GenericClientSessionConsumesAetheriaPlayableWorldSnapshotWithoutAetheriaTypes", "GenericProviderConnectionAppliesLiveSnapshotsAndSubmitsCommandsThroughSink", "ProviderSurfaceDocumentSourceFeedsPlayableClientWithoutAetheriaTypes", "PlayableWorldRuntimeComposesProviderDocumentsAssetsReceiptsAndSceneSink", "PlayableWorldClientHostMountsInterfaceProviderWithoutProviderTypes", "PlayableWorldClientHostSubmitsProviderOwnedMoveVector", "PlayableWorldInputDriverBuildsCameraRelativeMoveVectorWithoutProviderTypes", "PlayableWorldCameraRigFollowsAdvertisedPlayerEntityWithoutProviderTypes", "PlayableWorldPresenterInstantiatesUpdatesAndDespawnsProviderEntities", "LivePlayableWorldClientPresentsProviderSnapshotsAndKeepsCommandsProviderOwned", "LivePlayableWorldClientRefreshesFromProviderSnapshotAfterReceiptWithoutOwningMovement", "AssetManifestMapsProviderAssetRefsToUnityLoadKeysWithoutAetheriaTypes", "AssetManifestCacheTracksPlayableWorldManifestPointerAndLiveUpdates", "AssetManifestDocumentSourceFeedsCacheWithoutChangingSceneLowering", "FakeProviderSurfaceSource", "FakeProviderSurfaceDocumentSource", "FakeCommandReceiptSource", "FakeAssetManifestSource", "FakeAssetManifestDocumentSource", "FakeCommandSink", "FakePlayableWorldSceneSink", "FakePlayableWorldProviderComponent", "SaiVisualNovelLowersThroughRuntimeProjectionAdapterWithoutOwningStoryState", "CommandIntentCarriesAdvertisedBoundaryWithoutOwningReceipts", "pending", "reconciled", "world-projection-node", "playable-world-root", "playable-world-entity", "world-field-3d", "arpg-third-person", "cultmesh://aetheria/assets/manifest", "cultmesh://aetheria/eve/surfaces/aetheria.daemon.game", "aetheria.daemon.move_intent", "sai-vn-scene-stage", "norn-graph-scene-projection", "tex-math-scene-projection", "sai.vn", "norn.graph", "tex.math", "sidecar-advertised-plugin-abi", "aetheria.daemon.commands", "aetheria.eve_command_acceptance_status.v1")) { +foreach ($symbol in @("LowerCarriesProviderAdvertisedWorldBoundary", "LowerBuildsProviderAgnosticSceneGraphFromSurfaceTree", "LowerExtractsPlayableArpgWorldFromGenericScene3dSurface", "GenericClientSessionConsumesAetheriaPlayableWorldSnapshotWithoutAetheriaTypes", "GenericProviderConnectionAppliesLiveSnapshotsAndSubmitsCommandsThroughSink", "ProviderSurfaceDocumentSourceFeedsPlayableClientWithoutAetheriaTypes", "PlayableWorldRuntimeComposesProviderDocumentsAssetsReceiptsAndSceneSink", "PlayableWorldClientHostMountsInterfaceProviderWithoutProviderTypes", "PlayableWorldClientBootstrapWiresGenericUnityClientFromProviderInterfaces", "PlayableWorldClientHostSubmitsProviderOwnedMoveVector", "PlayableWorldInputDriverBuildsCameraRelativeMoveVectorWithoutProviderTypes", "PlayableWorldCameraRigFollowsAdvertisedPlayerEntityWithoutProviderTypes", "PlayableWorldPresenterInstantiatesUpdatesAndDespawnsProviderEntities", "LivePlayableWorldClientPresentsProviderSnapshotsAndKeepsCommandsProviderOwned", "LivePlayableWorldClientRefreshesFromProviderSnapshotAfterReceiptWithoutOwningMovement", "AssetManifestMapsProviderAssetRefsToUnityLoadKeysWithoutAetheriaTypes", "AssetManifestCacheTracksPlayableWorldManifestPointerAndLiveUpdates", "AssetManifestDocumentSourceFeedsCacheWithoutChangingSceneLowering", "FakeProviderSurfaceSource", "FakeProviderSurfaceDocumentSource", "FakeCommandReceiptSource", "FakeAssetManifestSource", "FakeAssetManifestDocumentSource", "FakeCommandSink", "FakePlayableWorldSceneSink", "FakePlayableWorldProviderComponent", "SaiVisualNovelLowersThroughRuntimeProjectionAdapterWithoutOwningStoryState", "CommandIntentCarriesAdvertisedBoundaryWithoutOwningReceipts", "pending", "reconciled", "world-projection-node", "playable-world-root", "playable-world-entity", "world-field-3d", "arpg-third-person", "cultmesh://aetheria/assets/manifest", "cultmesh://aetheria/eve/surfaces/aetheria.daemon.game", "aetheria.daemon.move_intent", "sai-vn-scene-stage", "norn-graph-scene-projection", "tex-math-scene-projection", "sai.vn", "norn.graph", "tex.math", "sidecar-advertised-plugin-abi", "aetheria.daemon.commands", "aetheria.eve_command_acceptance_status.v1")) { if (-not $testSource.Contains($symbol)) { throw "EveUnity scene provider shell tests missing symbol: $symbol" } diff --git a/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 b/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 index b5be002..bd52574 100644 --- a/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 +++ b/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 @@ -71,6 +71,10 @@ node $consumerScript $consumerExport ` --expect-runtime-feature unity-scene:livePlayableWorldClient ` --expect-runtime-feature unity-scene:providerCommandReceipts ` --expect-runtime-feature unity-scene:providerAssetManifestDocumentSource ` + --expect-runtime-feature unity-scene:playableWorldClientHost ` + --expect-runtime-feature unity-scene:playableWorldClientBootstrap ` + --expect-runtime-feature unity-scene:playableWorldInputDriver ` + --expect-runtime-feature unity-scene:playableWorldCameraRig ` --expect-runtime-feature unity-scene:sceneGraphProjection ` --expect-runtime-feature unity-scene:playableWorldProjection ` --expect-runtime-feature unity-scene:playableWorldRuntimeHost ` diff --git a/scripts/run-split-target-conformance-consumer-smoke.ps1 b/scripts/run-split-target-conformance-consumer-smoke.ps1 index 9c4ca62..98222db 100644 --- a/scripts/run-split-target-conformance-consumer-smoke.ps1 +++ b/scripts/run-split-target-conformance-consumer-smoke.ps1 @@ -51,8 +51,10 @@ try { --expect-split-target-blocker-record EveUnity:runtime-status:unity-scene ` --expect-split-target-blocker-record "EveUnity:pending-proof:Unity scene runtime body graduates to EveUnity outside Aetheria product code." ` --expect-split-handoff-move EveUnity:unity-scene:unity-scene-runtime-body:current:exists:EveUnitySceneSurfaceLowerer.cs ` + --expect-split-handoff-move EveUnity:unity-scene:unity-scene-runtime-body:current:exists:EveUnityPlayableWorldClientBootstrap.cs ` --expect-split-handoff-move EveUnity:unity-scene:unity-scene-upm-package:current:exists:eveunity-release-artifact.mjs ` --expect-split-handoff-move EveUnity:unity-scene:unity-scene-world-surface-lowering:current:exists:EveUnitySceneSurfaceLowerer.cs ` + --expect-split-handoff-move EveUnity:unity-scene:unity-scene-world-surface-lowering:current:exists:EveUnityPlayableWorldClientBootstrap.cs ` --expect-split-handoff-move EveUnity:unity-scene:unity-scene-sai-plugin-projection:current:exists:SaiVisualNovelUnitySceneProjectionAdapter.cs ` --expect-split-handoff-move EveUnity:unity-scene:unity-scene-norn-plugin-projection:current:exists:NornGraphUnitySceneProjectionAdapter.cs ` --expect-split-handoff-move EveUnity:unity-scene:unity-scene-tex-plugin-projection:current:exists:TeXMathUnitySceneProjectionAdapter.cs ` diff --git a/tools/parity/parity-manifest.json b/tools/parity/parity-manifest.json index e839d7d..cb9164b 100644 --- a/tools/parity/parity-manifest.json +++ b/tools/parity/parity-manifest.json @@ -1041,7 +1041,7 @@ "splitHandoffPath": "runtimes/incubating/eve-unity-scene/eveunity-scene-split-handoff.json", "requiredFixtures": ["aetheria-world", "eve-world-smoke"], "pluginFixtures": ["sai-vn"], - "supportedFeatures": ["providerAdvertisements", "commandTransport", "providerSurfaceSession", "providerSurfaceSource", "providerSurfaceDocumentSource", "livePlayableWorldClient", "providerCommandReceipts", "providerAssetManifestDocumentSource", "providerAssetManifestSource", "sceneGraphProjection", "playableWorldProjection", "playableWorldRuntimeHost", "playableWorldScenePresentation", "unityGameObjectSceneSink", "providerAssetManifestResolution", "embeddedDocuments"], + "supportedFeatures": ["providerAdvertisements", "commandTransport", "providerSurfaceSession", "providerSurfaceSource", "providerSurfaceDocumentSource", "livePlayableWorldClient", "providerCommandReceipts", "providerAssetManifestDocumentSource", "playableWorldClientHost", "playableWorldClientBootstrap", "playableWorldInputDriver", "playableWorldCameraRig", "providerAssetManifestSource", "sceneGraphProjection", "playableWorldProjection", "playableWorldRuntimeHost", "playableWorldScenePresentation", "unityGameObjectSceneSink", "providerAssetManifestResolution", "embeddedDocuments"], "supportedPlugins": [ { "pluginId": "sai.vn", @@ -1073,6 +1073,10 @@ "runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldLiveClient.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldInputDriver.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldCameraRig.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldPresenter.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityGameObjectPlayableWorldSceneSink.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldAssetManifest.cs", @@ -1093,6 +1097,10 @@ "runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldLiveClient.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldInputDriver.cs", + "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldCameraRig.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldPresenter.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityGameObjectPlayableWorldSceneSink.cs", "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldAssetManifest.cs", @@ -1137,7 +1145,23 @@ }, { "path": "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs", - "contains": ["EveUnityPlayableWorldRuntime", "CreateForGameObjectScene", "EveUnityLivePlayableWorldAssetProvider", "IEveUnitySceneProviderSurfaceDocumentSource", "IEveUnitySceneCommandSink", "IEveUnityPlayableWorldAssetManifestDocumentSource", "IEveUnitySceneCommandReceiptSource", "EveUnityPlayableWorldAssetManifestCache", "AssetManifests", "ActiveWorld", "SubmitMoveIntent", "SubmitFocusIntent", "SubmitTargetIntent", "SubmitActionIntent", "Connect", "Refresh", "Disconnect"] + "contains": ["EveUnityPlayableWorldRuntime", "CreateForGameObjectScene", "EveUnityLivePlayableWorldAssetProvider", "IEveUnitySceneProviderSurfaceDocumentSource", "IEveUnitySceneCommandSink", "IEveUnityPlayableWorldAssetManifestDocumentSource", "IEveUnitySceneCommandReceiptSource", "EveUnityPlayableWorldAssetManifestCache", "AssetManifests", "ActiveWorld", "SubmitMoveIntent", "SubmitMoveVectorIntent", "SubmitFocusIntent", "SubmitTargetIntent", "SubmitActionIntent", "Connect", "Refresh", "Disconnect"] + }, + { + "path": "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs", + "contains": ["EveUnityPlayableWorldClientHost", "MonoBehaviour", "providerSurfaceDocuments", "IEveUnitySceneProviderSurfaceDocumentSource", "IEveUnitySceneCommandSink", "IEveUnityPlayableWorldAssetManifestDocumentSource", "IEveUnitySceneCommandReceiptSource", "IEveUnityGameObjectAssetProvider", "IEveUnityProviderRefreshSource", "Configure", "ConnectOnEnable", "CreateForGameObjectScene", "Connect", "Refresh", "SceneRoot", "SubmitMoveIntent", "SubmitMoveVectorIntent", "SubmitFocusIntent", "SubmitTargetIntent", "SubmitActionIntent", "Disconnect"] + }, + { + "path": "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs", + "contains": ["EveUnityPlayableWorldClientBootstrap", "ConfigureProvider", "Mount", "ResolveHost", "ResolveSceneRoot", "ResolveCameraTransform", "EveUnityPlayableWorldClientHost", "EveUnityPlayableWorldInputDriver", "EveUnityPlayableWorldCameraRig", "IEveUnitySceneProviderSurfaceDocumentSource", "IEveUnitySceneCommandSink", "IEveUnityPlayableWorldAssetManifestDocumentSource", "IEveUnitySceneCommandReceiptSource", "IEveUnityGameObjectAssetProvider"] + }, + { + "path": "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldInputDriver.cs", + "contains": ["EveUnityPlayableWorldInputDriver", "EveUnityPlayableWorldMoveVector", "FromCameraRelativeInput", "SubmitMoveVectorInput", "SubmitPrimaryAction", "Input.GetAxisRaw", "Input.GetButtonDown", "directionX", "directionY", "scalarValue", "SubmitMoveVectorIntent"] + }, + { + "path": "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldCameraRig.cs", + "contains": ["EveUnityPlayableWorldCameraRig", "ApplyRig", "arpg.orbital-follow.v1", "EveUnityPlayableWorldEntityMarker", "SceneRoot", "LookAt"] }, { "path": "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldPresenter.cs", @@ -1165,7 +1189,7 @@ }, { "path": "runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs", - "contains": ["LowerCarriesProviderAdvertisedWorldBoundary", "LowerBuildsProviderAgnosticSceneGraphFromSurfaceTree", "LowerExtractsPlayableArpgWorldFromGenericScene3dSurface", "GenericClientSessionConsumesAetheriaPlayableWorldSnapshotWithoutAetheriaTypes", "GenericProviderConnectionAppliesLiveSnapshotsAndSubmitsCommandsThroughSink", "ProviderSurfaceDocumentSourceFeedsPlayableClientWithoutAetheriaTypes", "PlayableWorldRuntimeComposesProviderDocumentsAssetsReceiptsAndSceneSink", "PlayableWorldPresenterInstantiatesUpdatesAndDespawnsProviderEntities", "LivePlayableWorldClientPresentsProviderSnapshotsAndKeepsCommandsProviderOwned", "LivePlayableWorldClientRefreshesFromProviderSnapshotAfterReceiptWithoutOwningMovement", "AssetManifestMapsProviderAssetRefsToUnityLoadKeysWithoutAetheriaTypes", "AssetManifestCacheTracksPlayableWorldManifestPointerAndLiveUpdates", "AssetManifestDocumentSourceFeedsCacheWithoutChangingSceneLowering", "FakeProviderSurfaceSource", "FakeProviderSurfaceDocumentSource", "FakeCommandReceiptSource", "FakeAssetManifestSource", "FakeAssetManifestDocumentSource", "FakeCommandSink", "FakePlayableWorldSceneSink", "SaiVisualNovelLowersThroughRuntimeProjectionAdapterWithoutOwningStoryState", "CommandIntentCarriesAdvertisedBoundaryWithoutOwningReceipts", "pending", "reconciled", "world-projection-node", "playable-world-root", "playable-world-entity", "world-field-3d", "arpg-third-person", "cultmesh://aetheria/assets/manifest", "cultmesh://aetheria/eve/surfaces/aetheria.daemon.game", "aetheria.daemon.move_intent", "sai-vn-scene-stage", "norn-graph-scene-projection", "tex-math-scene-projection", "norn.map", "cultmesh://aetheria/norn/map", "sai.vn", "norn.graph", "tex.math", "sidecar-advertised-plugin-abi", "aetheria.daemon.commands", "aetheria.eve_command_acceptance_status.v1"] + "contains": ["LowerCarriesProviderAdvertisedWorldBoundary", "LowerBuildsProviderAgnosticSceneGraphFromSurfaceTree", "LowerExtractsPlayableArpgWorldFromGenericScene3dSurface", "GenericClientSessionConsumesAetheriaPlayableWorldSnapshotWithoutAetheriaTypes", "GenericProviderConnectionAppliesLiveSnapshotsAndSubmitsCommandsThroughSink", "ProviderSurfaceDocumentSourceFeedsPlayableClientWithoutAetheriaTypes", "PlayableWorldRuntimeComposesProviderDocumentsAssetsReceiptsAndSceneSink", "PlayableWorldClientHostMountsInterfaceProviderWithoutProviderTypes", "PlayableWorldClientBootstrapWiresGenericUnityClientFromProviderInterfaces", "PlayableWorldClientHostSubmitsProviderOwnedMoveVector", "PlayableWorldInputDriverBuildsCameraRelativeMoveVectorWithoutProviderTypes", "PlayableWorldCameraRigFollowsAdvertisedPlayerEntityWithoutProviderTypes", "PlayableWorldPresenterInstantiatesUpdatesAndDespawnsProviderEntities", "LivePlayableWorldClientPresentsProviderSnapshotsAndKeepsCommandsProviderOwned", "LivePlayableWorldClientRefreshesFromProviderSnapshotAfterReceiptWithoutOwningMovement", "AssetManifestMapsProviderAssetRefsToUnityLoadKeysWithoutAetheriaTypes", "AssetManifestCacheTracksPlayableWorldManifestPointerAndLiveUpdates", "AssetManifestDocumentSourceFeedsCacheWithoutChangingSceneLowering", "FakeProviderSurfaceSource", "FakeProviderSurfaceDocumentSource", "FakeCommandReceiptSource", "FakeAssetManifestSource", "FakeAssetManifestDocumentSource", "FakeCommandSink", "FakePlayableWorldSceneSink", "FakePlayableWorldProviderComponent", "SaiVisualNovelLowersThroughRuntimeProjectionAdapterWithoutOwningStoryState", "CommandIntentCarriesAdvertisedBoundaryWithoutOwningReceipts", "pending", "reconciled", "world-projection-node", "playable-world-root", "playable-world-entity", "world-field-3d", "arpg-third-person", "cultmesh://aetheria/assets/manifest", "cultmesh://aetheria/eve/surfaces/aetheria.daemon.game", "aetheria.daemon.move_intent", "sai-vn-scene-stage", "norn-graph-scene-projection", "tex-math-scene-projection", "norn.map", "cultmesh://aetheria/norn/map", "sai.vn", "norn.graph", "tex.math", "sidecar-advertised-plugin-abi", "aetheria.daemon.commands", "aetheria.eve_command_acceptance_status.v1"] }, { "path": "tools/eveunity/eveunity-capture-contract.test.mjs",