diff --git a/TestProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs b/TestProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs index 77bd210..bd73fb6 100644 --- a/TestProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs +++ b/TestProject/Assets/Tests/PlayMode/GenericWorldCaptureTests.cs @@ -205,7 +205,11 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests bridge = new EveUnitySceneLiveProviderBridge(transport); bridge.Connect(); runtime = EveUnityPlayableWorldRuntime.CreateForGameObjectScene( - root.transform, bridge, bridge, bridge, bridge); + root.transform, + bridge, + bridge, + assetManifestDocuments: null, + receiptSource: bridge); var initial = runtime.Connect(); Assert.That(initial.ActiveEntities, Is.GreaterThan(0)); Assert.That(runtime.ActiveWorld.PlayerEntityId, Is.Not.Empty); @@ -227,6 +231,10 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests Assert.That(runtime.LastReceipt, Is.Not.Null); Assert.That(runtime.LastReceipt.CommandId, Is.EqualTo(request.CommandId)); + Assert.That( + runtime.LastReceipt.State, + Is.EqualTo("accepted").Or.EqualTo("reconciled"), + runtime.LastReceipt.Message); Assert.That(runtime.LastReceipt.SourceVersion, Is.GreaterThan(initialVersion)); Assert.That(runtime.ActiveVersion, Is.GreaterThan(initialVersion)); Assert.That(Vector3.Distance(FindMarker(root, playerId).transform.position, initialPosition), Is.GreaterThan(0.01f)); @@ -238,8 +246,20 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests var camera = cameraObject.AddComponent(); camera.clearFlags = CameraClearFlags.SolidColor; camera.backgroundColor = new Color(0.035f, 0.055f, 0.08f, 1f); - camera.transform.position = new Vector3(14f, 12f, -16f); - camera.transform.LookAt(FindMarker(root, playerId).transform.position); + foreach (var entityMarker in root.GetComponentsInChildren()) + { + var renderer = entityMarker.GetComponent(); + renderer.material.color = entityMarker.Controllable + ? new Color(0.18f, 0.75f, 1f) + : entityMarker.EntityKind == "enemy" + ? new Color(1f, 0.25f, 0.2f) + : new Color(1f, 0.78f, 0.15f); + } + var playerMarker = FindMarker(root, playerId); + var playerBounds = playerMarker.GetComponent().bounds; + var cameraDistance = Mathf.Max(8f, playerBounds.extents.magnitude * 4f); + camera.transform.position = playerBounds.center + new Vector3(1f, 0.8f, -1.2f).normalized * cameraDistance; + camera.transform.LookAt(playerBounds.center); target = new RenderTexture(640, 360, 24, RenderTextureFormat.ARGB32); camera.targetTexture = target; yield return null; diff --git a/packages/org.gamecult.eve.unity-scene/Runtime/EveUnitySceneSurfaceLowerer.cs b/packages/org.gamecult.eve.unity-scene/Runtime/EveUnitySceneSurfaceLowerer.cs index 6c02fef..b098b05 100644 --- a/packages/org.gamecult.eve.unity-scene/Runtime/EveUnitySceneSurfaceLowerer.cs +++ b/packages/org.gamecult.eve.unity-scene/Runtime/EveUnitySceneSurfaceLowerer.cs @@ -51,7 +51,7 @@ namespace GameCult.Eve.UnityScene return new EveSurfaceCommandRequest( projection.ProviderId, projection.SurfaceId, - ResolveOperation(document, command), + ResolveOperation(document, command, $"unity-scene-{Guid.NewGuid():N}"), CultMesh.OperationPayload(payload ?? new Dictionary(StringComparer.Ordinal)), issuedAt ?? DateTimeOffset.UtcNow, "unity-scene", @@ -61,15 +61,16 @@ namespace GameCult.Eve.UnityScene private static CultMeshOperationInvocationDescriptor ResolveOperation( EveSurfaceDocument document, - string command) + string command, + string idempotencyKey) { foreach (var template in document.Commands) { if (string.Equals(template.Command, command, StringComparison.Ordinal)) - return CultMesh.OperationInvocation(template.Operation); + return CultMesh.OperationInvocation(template.Operation, idempotencyKey); } - return CultMesh.OperationInvocation(command); + return CultMesh.OperationInvocation(command, idempotencyKey: idempotencyKey); } private static EveUnitySceneNode BuildSceneGraph(EveSurfaceComponent component) diff --git a/scripts/run-aetheria-daemon-world-witness.ps1 b/scripts/run-aetheria-daemon-world-witness.ps1 index 726c6a8..ab8c534 100644 --- a/scripts/run-aetheria-daemon-world-witness.ps1 +++ b/scripts/run-aetheria-daemon-world-witness.ps1 @@ -23,7 +23,14 @@ foreach ($required in @($UnityExe, $projectRoot, $daemonProject, (Join-Path $Cul } New-Item -ItemType Directory -Force -Path $outputRoot | Out-Null -foreach ($ephemeralPath in @($replicaPath, $statePath)) { +foreach ($ephemeralPath in @( + $replicaPath, + "$replicaPath.records", + "$replicaPath.cultmesh", + $statePath, + "$statePath.records", + "$statePath.cultmesh" +)) { $resolved = [IO.Path]::GetFullPath($ephemeralPath) if (-not $resolved.StartsWith([IO.Path]::GetFullPath($outputRoot), [StringComparison]::OrdinalIgnoreCase)) { throw "Witness cleanup escaped its artifact directory: $resolved" @@ -42,6 +49,7 @@ $daemonArguments = @( "--client-cultmesh-port", $Port, "--no-odin-announcements" ) +$env:AETHERIA_TRACE_EVE_SNAPSHOTS = "1" $daemon = Start-Process -FilePath "dotnet" -ArgumentList $daemonArguments -PassThru -WindowStyle Hidden ` -RedirectStandardOutput $daemonLogPath -RedirectStandardError (Join-Path $outputRoot "aetheria-daemon.error.log") Write-Host "Aetheria daemon PID: $($daemon.Id)" @@ -86,4 +94,5 @@ try { finally { if ($null -ne $daemon -and -not $daemon.HasExited) { Stop-Process -Id $daemon.Id -Force } Remove-Item Env:EVEUNITY_PROVIDER_ENDPOINT, Env:EVEUNITY_PROVIDER_ID, Env:EVEUNITY_SURFACE_ID, Env:EVEUNITY_REPLICA_PATH, Env:EVEUNITY_AETHERIA_CAPTURE_PATH -ErrorAction SilentlyContinue + Remove-Item Env:AETHERIA_TRACE_EVE_SNAPSHOTS -ErrorAction SilentlyContinue }