diff --git a/docs/eve-migration-roadmap.md b/docs/eve-migration-roadmap.md index 879cf8a..94840c2 100644 --- a/docs/eve-migration-roadmap.md +++ b/docs/eve-migration-roadmap.md @@ -614,6 +614,12 @@ Recently cut: movement/focus/target/action intents through the advertised command boundary, while `EveUnitySceneProviderConnection` defines the generic surface source and command sink ports that a CultMesh/CultNet adapter must implement. + `IEveUnitySceneProviderSurfaceDocumentSource`, + `EveUnitySceneProviderSurfaceDocument`, and + `EveUnitySceneProviderSurfaceDocumentSource` now add the typed provider + document boundary in front of those snapshots, so live CultMesh/CultCache + readers can publish daemon-owned surface documents without teaching EveUnity + Aetheria types. `EveUnityPlayableWorldLiveClient` now composes the provider connection with the playable-world presenter, so provider snapshots immediately drive scene presentation and Unity input still exits through the provider command sink @@ -640,7 +646,7 @@ Recently cut: Aetheria asset classes. 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 snapshots and asset manifest documents, and prove + 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 diff --git a/docs/parity-testing-harness.md b/docs/parity-testing-harness.md index 93b905c..a5cf92a 100644 --- a/docs/parity-testing-harness.md +++ b/docs/parity-testing-harness.md @@ -485,6 +485,12 @@ types. It also declares `providerSurfaceSource` through `EveUnitySceneProviderConnection`, `IEveUnitySceneProviderSurfaceSource`, and `IEveUnitySceneCommandSink`, so the live CultMesh/CultNet adapter has a narrow runtime-owned port to implement. The runtime now also declares +`providerSurfaceDocumentSource`: `IEveUnitySceneProviderSurfaceDocumentSource`, +`EveUnitySceneProviderSurfaceDocument`, and +`EveUnitySceneProviderSurfaceDocumentSource` convert provider-authored surface +documents into snapshots before lowering, so the future CultMesh/CultCache +reader can own document delivery without importing Aetheria types. The runtime +now also declares `livePlayableWorldClient`: `EveUnityPlayableWorldLiveClient` composes the provider connection with `EveUnityPlayableWorldPresenter`, applies every live snapshot to the scene sink, and delegates player intent back to the advertised @@ -514,8 +520,8 @@ declares `providerAssetManifestDocumentSource`: `EveUnityPlayableWorldAssetManifestDocumentSource` convert provider-authored manifest documents into the runtime cache without importing Aetheria asset classes. The remaining blocker is the live CultMesh/CultNet adapter, concrete -CultMesh/CultCache readers for provider snapshots and asset manifests, and Unity -screenshot or frame-capture PNG production from EveUnity. +CultMesh/CultCache readers for provider surface and asset manifest documents, +and Unity screenshot or frame-capture PNG production from EveUnity. Runtime capture probe coverage is exported as `runtimeCaptureProbeCoverage[]`. Each record joins runtime status, capture owner, lifecycle capture contract, diff --git a/docs/world-state-lowering.md b/docs/world-state-lowering.md index 93475ba..09535fd 100644 --- a/docs/world-state-lowering.md +++ b/docs/world-state-lowering.md @@ -164,6 +164,12 @@ radii, asset refs, controllability, and command affordances. The generic `EveUnitySceneProviderConnection` adds the live-source port shape: `IEveUnitySceneProviderSurfaceSource` supplies current and updated snapshots, while `IEveUnitySceneCommandSink` receives command envelopes. +`IEveUnitySceneProviderSurfaceDocumentSource`, +`EveUnitySceneProviderSurfaceDocument`, and +`EveUnitySceneProviderSurfaceDocumentSource` now make that snapshot source a +typed document-consumer boundary: a CultMesh/CultCache adapter can own surface +delivery and publish provider-authored documents, while EveUnity only converts +them into snapshots for the generic lowerer. `EveUnityPlayableWorldLiveClient` composes that connection with the playable world presenter: every provider snapshot is lowered into a presentation pass, Unity input still emits provider-owned command intents rather than mutating @@ -193,10 +199,10 @@ does not import Aetheria runtime types, prefab classes, or apply movement locally. This is not yet the final playable client. The remaining cut is a live -CultMesh/CultNet provider subscription adapter implementing those source/sink -ports, concrete CultMesh/CultCache readers for provider snapshots and asset -manifest documents, and proof that daemon receipts plus provider snapshots drive -the next rendered Unity frame rather than renderer-local state. +CultMesh/CultNet provider subscription adapter implementing those document and +command ports, concrete CultMesh/CultCache readers for provider snapshots and +asset manifest documents, and proof that daemon receipts plus provider +snapshots drive the next rendered Unity frame rather than renderer-local state. ## Non-Goals diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs b/runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs index d3c2a28..a8b7a75 100644 --- a/runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs @@ -16,6 +16,10 @@ namespace GameCult.Eve.UnityScene EveUnitySceneProviderSurfaceSnapshot CurrentSnapshot { get; } event Action SnapshotAvailable; + + void Connect(); + + void Disconnect(); } public interface IEveUnitySceneCommandSink @@ -25,6 +29,98 @@ namespace GameCult.Eve.UnityScene void Submit(EveSurfaceCommandRequest request); } + public interface IEveUnitySceneProviderSurfaceDocumentSource + { + EveUnitySceneProviderSurfaceDocument CurrentDocument { get; } + + event Action DocumentAvailable; + } + + public sealed class EveUnitySceneProviderSurfaceDocument + { + public EveUnitySceneProviderSurfaceDocument( + EveSurfaceDocument surfaceDocument, + EveUnitySceneProviderSurfaceAdvertisement advertisedSurface, + string sourcePointer, + long version = 0) + { + SurfaceDocument = surfaceDocument ?? throw new ArgumentNullException(nameof(surfaceDocument)); + AdvertisedSurface = advertisedSurface ?? throw new ArgumentNullException(nameof(advertisedSurface)); + SourcePointer = sourcePointer ?? ""; + Version = version == 0 ? surfaceDocument.Version : version; + } + + public EveSurfaceDocument SurfaceDocument { get; } + + public EveUnitySceneProviderSurfaceAdvertisement AdvertisedSurface { get; } + + public string SourcePointer { get; } + + public long Version { get; } + + public EveUnitySceneProviderSurfaceSnapshot ToSnapshot() + { + return new EveUnitySceneProviderSurfaceSnapshot( + SurfaceDocument, + AdvertisedSurface, + SourcePointer, + Version); + } + } + + public sealed class EveUnitySceneProviderSurfaceDocumentSource : IEveUnitySceneProviderSurfaceSource, IDisposable + { + private readonly IEveUnitySceneProviderSurfaceDocumentSource _documentSource; + private bool _connected; + + public EveUnitySceneProviderSurfaceDocumentSource( + IEveUnitySceneProviderSurfaceDocumentSource documentSource) + { + _documentSource = documentSource ?? throw new ArgumentNullException(nameof(documentSource)); + CurrentSnapshot = _documentSource.CurrentDocument.ToSnapshot(); + } + + public string ProviderId => CurrentSnapshot.Document.ProviderId; + + public string SurfaceId => CurrentSnapshot.AdvertisedSurface.SurfaceId; + + public string SourcePointer => CurrentSnapshot.SourcePointer; + + public EveUnitySceneProviderSurfaceSnapshot CurrentSnapshot { get; private set; } + + public event Action? SnapshotAvailable; + + public void Connect() + { + if (_connected) + return; + + _documentSource.DocumentAvailable += OnDocumentAvailable; + _connected = true; + } + + public void Disconnect() + { + if (!_connected) + return; + + _documentSource.DocumentAvailable -= OnDocumentAvailable; + _connected = false; + } + + public void Dispose() + { + Disconnect(); + } + + private void OnDocumentAvailable(EveUnitySceneProviderSurfaceDocument document) + { + if (document == null) throw new ArgumentNullException(nameof(document)); + CurrentSnapshot = document.ToSnapshot(); + SnapshotAvailable?.Invoke(CurrentSnapshot); + } + } + public sealed class EveUnitySceneProviderConnection : IDisposable { private readonly IEveUnitySceneProviderSurfaceSource _surfaceSource; @@ -66,6 +162,7 @@ namespace GameCult.Eve.UnityScene if (!_connected) { _surfaceSource.SnapshotAvailable += OnSnapshotAvailable; + _surfaceSource.Connect(); _connected = true; } @@ -116,6 +213,7 @@ namespace GameCult.Eve.UnityScene return; _surfaceSource.SnapshotAvailable -= OnSnapshotAvailable; + _surfaceSource.Disconnect(); _connected = false; } diff --git a/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs b/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs index 781a740..4047fea 100644 --- a/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs +++ b/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs @@ -198,6 +198,56 @@ namespace GameCult.Eve.UnityScene.Tests Assert.That(projectionUpdates, Is.EqualTo(2)); } + [Test] + public void ProviderSurfaceDocumentSourceFeedsPlayableClientWithoutAetheriaTypes() + { + var documentSource = new FakeProviderSurfaceDocumentSource(new EveUnitySceneProviderSurfaceDocument( + PlayableArpgDocument(), + Advertisement("aetheria.daemon.game"), + "cultmesh://aetheria/eve/surfaces/aetheria.daemon.game", + 1)); + using var surfaceSource = new EveUnitySceneProviderSurfaceDocumentSource(documentSource); + var commandSink = new FakeCommandSink("cultmesh-command-sink"); + var sceneSink = new FakePlayableWorldSceneSink(); + using var connection = new EveUnitySceneProviderConnection(surfaceSource, commandSink); + using var client = new EveUnityPlayableWorldLiveClient( + connection, + new EveUnityPlayableWorldPresenter(sceneSink, new EveUnityAssetRefResolver())); + + var initialPresentation = client.Connect(); + + Assert.That(surfaceSource.ProviderId, Is.EqualTo("aetheria")); + Assert.That(surfaceSource.SurfaceId, Is.EqualTo("aetheria.daemon.game")); + Assert.That(surfaceSource.SourcePointer, Is.EqualTo("cultmesh://aetheria/eve/surfaces/aetheria.daemon.game")); + Assert.That(initialPresentation.ActiveEntities, Is.EqualTo(3)); + Assert.That(client.ActiveWorld, Is.Not.Null); + Assert.That(client.ActiveWorld!.StatePointerId, Is.EqualTo("cultmesh://aetheria/run/current")); + Assert.That(client.ActiveWorld.AssetManifest, Is.EqualTo("cultmesh://aetheria/assets/manifest")); + + documentSource.Publish(new EveUnitySceneProviderSurfaceDocument( + PlayableArpgDocument(includeRaider: false, playerPosition: "11,0,5"), + Advertisement("aetheria.daemon.game"), + "cultmesh://aetheria/eve/surfaces/aetheria.daemon.game", + 2)); + + Assert.That(client.ActiveVersion, Is.EqualTo(2)); + Assert.That(client.LastPresentation, Is.Not.Null); + Assert.That(client.LastPresentation!.ActiveEntities, Is.EqualTo(2)); + Assert.That(sceneSink.RemovedEntityIds, Does.Contain("raider-scout")); + Assert.That(sceneSink.Upserts[3].entity.EntityId, Is.EqualTo("player-vanguard")); + Assert.That(sceneSink.Upserts[3].entity.PositionX, Is.EqualTo(11f)); + Assert.That(sceneSink.Upserts[3].entity.PositionZ, Is.EqualTo(5f)); + + var moveIntent = client.SubmitMoveIntent("player-vanguard", 12f, 0f, 8f); + + Assert.That(commandSink.Submitted.Count, Is.EqualTo(1)); + Assert.That(commandSink.Submitted[0], Is.SameAs(moveIntent)); + Assert.That(moveIntent.ProviderId, Is.EqualTo("aetheria")); + Assert.That(moveIntent.SurfaceId, Is.EqualTo("aetheria.daemon.game")); + Assert.That(moveIntent.CommandBoundary, Is.EqualTo("aetheria.daemon.commands")); + Assert.That(moveIntent.ReceiptSchema, Is.EqualTo("aetheria.eve_command_acceptance_status.v1")); + } + [Test] public void PlayableWorldPresenterInstantiatesUpdatesAndDespawnsProviderEntities() { @@ -934,6 +984,14 @@ namespace GameCult.Eve.UnityScene.Tests public event Action? SnapshotAvailable; + public void Connect() + { + } + + public void Disconnect() + { + } + public void Stage(EveUnitySceneProviderSurfaceSnapshot snapshot) { CurrentSnapshot = snapshot; @@ -946,6 +1004,24 @@ namespace GameCult.Eve.UnityScene.Tests } } + private sealed class FakeProviderSurfaceDocumentSource : IEveUnitySceneProviderSurfaceDocumentSource + { + public FakeProviderSurfaceDocumentSource(EveUnitySceneProviderSurfaceDocument currentDocument) + { + CurrentDocument = currentDocument; + } + + public EveUnitySceneProviderSurfaceDocument CurrentDocument { get; private set; } + + public event Action? DocumentAvailable; + + public void Publish(EveUnitySceneProviderSurfaceDocument document) + { + CurrentDocument = document; + DocumentAvailable?.Invoke(document); + } + } + private sealed class FakeCommandReceiptSource : IEveUnitySceneCommandReceiptSource { public event Action? ReceiptAvailable; diff --git a/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json b/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json index 78f82cd..a5b0be2 100644 --- a/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json +++ b/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json @@ -18,6 +18,7 @@ "commandTransport", "providerSurfaceSession", "providerSurfaceSource", + "providerSurfaceDocumentSource", "livePlayableWorldClient", "providerCommandReceipts", "providerAssetManifestDocumentSource", @@ -178,7 +179,7 @@ ], "pendingProofs": [ "Unity scene provider-advertisement smoke runs from EveUnity with real Unity scene/frame objects and no Aetheria imports.", - "Live CultMesh/CultNet provider subscription adapter implements IEveUnitySceneProviderSurfaceSource and feeds EveUnitySceneClientSession snapshots instead of Eve-local fixture documents." + "Live CultMesh/CultNet provider subscription adapter implements IEveUnitySceneProviderSurfaceDocumentSource/IEveUnitySceneProviderSurfaceSource and feeds EveUnitySceneClientSession snapshots from provider-owned documents instead of Eve-local fixture documents." ] }, "capture": { 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 604e212..ce4dd9e 100644 --- a/runtimes/incubating/eve-unity-scene/eveunity-scene-split-handoff.json +++ b/runtimes/incubating/eve-unity-scene/eveunity-scene-split-handoff.json @@ -73,7 +73,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, provider snapshot session, 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, 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", @@ -122,7 +122,7 @@ "runtimes/incubating/eve-unity-scene/eve-runtime-capability.json" ], "destinationOwner": "EveUnity", - "replacementProof": "Unity scene input emits gamecult.eve.command.v1 intents through a provider-snapshot client session, IEveUnitySceneProviderSurfaceSource, IEveUnitySceneCommandSink, IEveUnitySceneCommandReceiptSource, and advertised command boundaries, then observes provider receipts and refreshes from provider snapshots instead of mutating local world truth." + "replacementProof": "Unity scene input emits gamecult.eve.command.v1 intents through typed provider surface documents, a provider-snapshot client session, IEveUnitySceneProviderSurfaceSource, IEveUnitySceneCommandSink, IEveUnitySceneCommandReceiptSource, and advertised command boundaries, then observes provider receipts and refreshes from provider documents/snapshots instead of mutating local world truth." }, { "id": "unity-scene-capture-lifecycle", @@ -161,7 +161,7 @@ "EveUnity builds the provider-agnostic Unity scene UPM package artifact.", "EveUnity owns a provider-agnostic scene graph lowerer that consumes advertised worldInteraction boundaries without importing Aetheria internals.", "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 provider surface source and command sink ports that a live CultMesh/CultNet adapter can implement without changing scene lowering.", + "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 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.", @@ -175,7 +175,7 @@ "EveUnity lowers at least one non-Aetheria provider-authored world surface into Unity scene objects.", "EveUnity lowers Aetheria's game world surface into generic playableWorld projection data through provider advertisements without importing Aetheria internals.", "A generic EveUnity scene client subscribes to the live Aetheria daemon surface over CultMesh/CultNet without Aetheria project code.", - "Unity scene input emits gamecult.eve.command.v1 intents, observes provider receipts, and refreshes rendered state from provider snapshots.", + "Unity scene input emits gamecult.eve.command.v1 intents, observes provider receipts, and refreshes rendered state from provider surface documents/snapshots.", "Unity scene screenshot or frame-capture PNG artifacts are attached to conformance output." ] } diff --git a/scripts/run-eveunity-scene-lifecycle-smoke.ps1 b/scripts/run-eveunity-scene-lifecycle-smoke.ps1 index 70f7f76..ba2a886 100644 --- a/scripts/run-eveunity-scene-lifecycle-smoke.ps1 +++ b/scripts/run-eveunity-scene-lifecycle-smoke.ps1 @@ -39,7 +39,7 @@ if ($manifest.incubation.splitHandoff.manifestPath -ne "runtimes/incubating/eve- throw "EveUnity scene manifest missing split handoff path" } -foreach ($feature in @("providerAdvertisements", "commandTransport", "providerSurfaceSession", "providerSurfaceSource", "livePlayableWorldClient", "providerCommandReceipts", "providerAssetManifestDocumentSource", "sceneGraphProjection", "playableWorldProjection", "playableWorldScenePresentation", "unityGameObjectSceneSink", "providerAssetManifestResolution", "providerAssetManifestSource", "embeddedDocuments")) { +foreach ($feature in @("providerAdvertisements", "commandTransport", "providerSurfaceSession", "providerSurfaceSource", "providerSurfaceDocumentSource", "livePlayableWorldClient", "providerCommandReceipts", "providerAssetManifestDocumentSource", "sceneGraphProjection", "playableWorldProjection", "playableWorldScenePresentation", "unityGameObjectSceneSink", "providerAssetManifestResolution", "providerAssetManifestSource", "embeddedDocuments")) { if (-not (@($manifest.supportedFeatures) -contains $feature)) { throw "EveUnity scene manifest missing provider-shell feature: $feature" } diff --git a/scripts/run-eveunity-scene-provider-shell-smoke.ps1 b/scripts/run-eveunity-scene-provider-shell-smoke.ps1 index 1e288e9..5089bd8 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", "livePlayableWorldClient", "providerCommandReceipts", "providerAssetManifestDocumentSource", "sceneGraphProjection", "playableWorldProjection", "playableWorldScenePresentation", "unityGameObjectSceneSink", "providerAssetManifestResolution", "providerAssetManifestSource")) { +foreach ($feature in @("providerAdvertisements", "commandTransport", "providerSurfaceSession", "providerSurfaceSource", "providerSurfaceDocumentSource", "livePlayableWorldClient", "providerCommandReceipts", "providerAssetManifestDocumentSource", "sceneGraphProjection", "playableWorldProjection", "playableWorldScenePresentation", "unityGameObjectSceneSink", "providerAssetManifestResolution", "providerAssetManifestSource")) { if (-not (@($manifest.supportedFeatures) -contains $feature)) { throw "EveUnity scene provider shell missing supported feature: $feature" } @@ -99,7 +99,7 @@ foreach ($symbol in @("EveUnitySceneClientSession", "EveUnitySceneProviderSurfac } $providerConnectionSource = Get-Content -LiteralPath (Join-Path $projectRoot "runtimes\incubating\eve-unity-scene\Runtime\EveUnitySceneProviderConnection.cs") -Raw -foreach ($symbol in @("IEveUnitySceneProviderSurfaceSource", "IEveUnitySceneCommandSink", "EveUnitySceneProviderConnection", "SnapshotAvailable", "CurrentSnapshot", "Connect", "Refresh", "SubmitMoveIntent", "SubmitFocusIntent", "SubmitTargetIntent", "SubmitActionIntent", "Disconnect")) { +foreach ($symbol in @("IEveUnitySceneProviderSurfaceSource", "IEveUnitySceneCommandSink", "IEveUnitySceneProviderSurfaceDocumentSource", "EveUnitySceneProviderSurfaceDocument", "EveUnitySceneProviderSurfaceDocumentSource", "ToSnapshot", "DocumentAvailable", "EveUnitySceneProviderConnection", "SnapshotAvailable", "CurrentSnapshot", "Connect", "Refresh", "SubmitMoveIntent", "SubmitFocusIntent", "SubmitTargetIntent", "SubmitActionIntent", "Disconnect")) { if (-not $providerConnectionSource.Contains($symbol)) { throw "EveUnity scene provider connection missing symbol: $symbol" } @@ -155,7 +155,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", "PlayableWorldPresenterInstantiatesUpdatesAndDespawnsProviderEntities", "LivePlayableWorldClientPresentsProviderSnapshotsAndKeepsCommandsProviderOwned", "LivePlayableWorldClientRefreshesFromProviderSnapshotAfterReceiptWithoutOwningMovement", "AssetManifestMapsProviderAssetRefsToUnityLoadKeysWithoutAetheriaTypes", "AssetManifestCacheTracksPlayableWorldManifestPointerAndLiveUpdates", "AssetManifestDocumentSourceFeedsCacheWithoutChangingSceneLowering", "FakeProviderSurfaceSource", "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", "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", "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", "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 b7e1620..15ee149 100644 --- a/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 +++ b/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 @@ -67,6 +67,7 @@ node $consumerScript $consumerExport ` --expect-runtime-feature unity-scene:commandTransport ` --expect-runtime-feature unity-scene:providerSurfaceSession ` --expect-runtime-feature unity-scene:providerSurfaceSource ` + --expect-runtime-feature unity-scene:providerSurfaceDocumentSource ` --expect-runtime-feature unity-scene:livePlayableWorldClient ` --expect-runtime-feature unity-scene:providerCommandReceipts ` --expect-runtime-feature unity-scene:providerAssetManifestDocumentSource ` diff --git a/tools/parity/parity-manifest.json b/tools/parity/parity-manifest.json index 6f6696e..d6db110 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", "livePlayableWorldClient", "providerCommandReceipts", "providerAssetManifestDocumentSource", "providerAssetManifestSource", "sceneGraphProjection", "playableWorldProjection", "playableWorldScenePresentation", "unityGameObjectSceneSink", "providerAssetManifestResolution", "embeddedDocuments"], + "supportedFeatures": ["providerAdvertisements", "commandTransport", "providerSurfaceSession", "providerSurfaceSource", "providerSurfaceDocumentSource", "livePlayableWorldClient", "providerCommandReceipts", "providerAssetManifestDocumentSource", "providerAssetManifestSource", "sceneGraphProjection", "playableWorldProjection", "playableWorldScenePresentation", "unityGameObjectSceneSink", "providerAssetManifestResolution", "embeddedDocuments"], "supportedPlugins": [ { "pluginId": "sai.vn", @@ -1127,7 +1127,7 @@ }, { "path": "runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs", - "contains": ["IEveUnitySceneProviderSurfaceSource", "IEveUnitySceneCommandSink", "EveUnitySceneProviderConnection", "SnapshotAvailable", "CurrentSnapshot", "Connect", "Refresh", "SubmitMoveIntent", "SubmitFocusIntent", "SubmitTargetIntent", "SubmitActionIntent", "Disconnect"] + "contains": ["IEveUnitySceneProviderSurfaceSource", "IEveUnitySceneCommandSink", "IEveUnitySceneProviderSurfaceDocumentSource", "EveUnitySceneProviderSurfaceDocument", "EveUnitySceneProviderSurfaceDocumentSource", "ToSnapshot", "DocumentAvailable", "EveUnitySceneProviderConnection", "SnapshotAvailable", "CurrentSnapshot", "Connect", "Refresh", "SubmitMoveIntent", "SubmitFocusIntent", "SubmitTargetIntent", "SubmitActionIntent", "Disconnect"] }, { "path": "runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldLiveClient.cs", @@ -1159,7 +1159,7 @@ }, { "path": "runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs", - "contains": ["LowerCarriesProviderAdvertisedWorldBoundary", "LowerBuildsProviderAgnosticSceneGraphFromSurfaceTree", "LowerExtractsPlayableArpgWorldFromGenericScene3dSurface", "GenericClientSessionConsumesAetheriaPlayableWorldSnapshotWithoutAetheriaTypes", "GenericProviderConnectionAppliesLiveSnapshotsAndSubmitsCommandsThroughSink", "PlayableWorldPresenterInstantiatesUpdatesAndDespawnsProviderEntities", "LivePlayableWorldClientPresentsProviderSnapshotsAndKeepsCommandsProviderOwned", "LivePlayableWorldClientRefreshesFromProviderSnapshotAfterReceiptWithoutOwningMovement", "AssetManifestMapsProviderAssetRefsToUnityLoadKeysWithoutAetheriaTypes", "AssetManifestCacheTracksPlayableWorldManifestPointerAndLiveUpdates", "AssetManifestDocumentSourceFeedsCacheWithoutChangingSceneLowering", "FakeProviderSurfaceSource", "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", "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"] }, { "path": "tools/eveunity/eveunity-capture-contract.test.mjs",