diff --git a/Aetheria.State.Smoke/Program.cs b/Aetheria.State.Smoke/Program.cs index 8eb34eed1..c04050401 100644 --- a/Aetheria.State.Smoke/Program.cs +++ b/Aetheria.State.Smoke/Program.cs @@ -731,14 +731,17 @@ await using (var reopened = await AetheriaStateNode.OpenAsync(statePath, "aether !advertisement.Schemas.Contains(AetheriaRuntimeDaemonSchemas.GameSurface) || !advertisement.Schemas.Contains(AetheriaRuntimeDaemonSchemas.EditorSurface) || !advertisement.Witnesses.Any(witness => - witness.Kind == "cultcache-witness" && - witness.Ref == AetheriaRuntimeStateBoundary.GetDaemonProviderPath(statePath)) || + witness.Kind == "cultcache" && + witness.Ref == statePath) || !advertisement.Witnesses.Any(witness => - witness.Kind == "cultcache-witness" && - witness.Ref == AetheriaRuntimeStateBoundary.GetDaemonCommandBoundaryPath(statePath)) || + witness.Kind == "cultmesh-record" && + witness.Ref == AetheriaRuntimeVerseRecordKeys.DaemonProviderAdvertisement.ToString()) || + !advertisement.Witnesses.Any(witness => + witness.Kind == "cultmesh-record" && + witness.Ref == AetheriaRuntimeVerseRecordKeys.DaemonCommandBoundary.ToString()) || !advertisement.Commands.Any(command => command.Command == "aetheria.daemon.commands" && - command.Transport == "cultcache-witness") || + command.Transport == "cultmesh") || !advertisement.Commands.Any(command => command.Command == "aetheria.player_settings.graphics.show_asteroids.toggle") || !advertisement.Schemas.Contains(AetheriaEveCommandBridge.CommandSchema)) { diff --git a/Aetheria.State.Verify/Program.cs b/Aetheria.State.Verify/Program.cs index 3f348e154..949bc7a15 100644 --- a/Aetheria.State.Verify/Program.cs +++ b/Aetheria.State.Verify/Program.cs @@ -571,7 +571,7 @@ Console.WriteLine($"Described/geoname-linked corporations: {describedCorporation Console.WriteLine($"Corporation allegiance edges: {corporationAllegianceEdges}"); Console.WriteLine($"Name files: {nameFiles.Length}"); Console.WriteLine("Live gameplay source purity: no serializer or legacy database symbols in Assets/Scripts"); -Console.WriteLine("Package serializer boundary: MessagePack symbols remain in named CultCache transport files only"); +Console.WriteLine("Package serializer boundary: MessagePack execution remains in named CultCache transport files; document DTOs may carry schema annotations"); Console.WriteLine("Shared Eve package ownership: generic Unity Eve packages import from the neighboring Eve repo instead of local staged copies"); Console.WriteLine("Typed runtime behavior coverage: live behavior kinds have typed factory plus progress/state restore coverage"); Console.WriteLine("Zone construction/runtime key authority: body/orbit wrappers and task shells retain typed keys instead of GUID sidecars"); @@ -873,7 +873,7 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root) !runtimeSurfaceDocuments.Contains("public IReadOnlyList StateBindings", StringComparison.Ordinal) || !runtimeSurfaceDocuments.Contains("public IReadOnlyList EmbeddedDocuments", StringComparison.Ordinal) || !runtimeSurfaceDocuments.Contains("public sealed class AetheriaRuntimeEmbeddedDocumentSlot", StringComparison.Ordinal) || - !runtimeSurfaceBuilder.Contains("public static CultMeshStateBindingDescriptor ForDaemonStateRef(", StringComparison.Ordinal) || + !runtimeSurfaceDocuments.Contains("public static CultMeshStateBindingDescriptor ForDaemonStateRef(", StringComparison.Ordinal) || !runtimeSurfaceDocuments.Contains("public CultMeshOperationBindingDescriptor Operation", StringComparison.Ordinal)) { throw new InvalidOperationException( @@ -888,10 +888,10 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root) "Aetheria runtime surfaces no longer hand CultMesh state bindings and embedded document slots to the shared Eve component model."); } - if (!runtimeSurfaceBuilder.Contains("CultMesh.StateBindingRecord(binding)", StringComparison.Ordinal) || + if (!runtimeSurfaceDocuments.Contains("CultMesh.StateBindingRecord(binding)", StringComparison.Ordinal) || !runtimeSurfaceDocuments.Contains("CultMesh.StateBindingRecord(", StringComparison.Ordinal) || !runtimeSurfaceDocuments.Contains(".ToBinding()", StringComparison.Ordinal) || - runtimeSurfaceBuilder.Contains("CultMesh.RouteRecord(binding.RouteHint)", StringComparison.Ordinal) || + runtimeSurfaceDocuments.Contains("CultMesh.RouteRecord(binding.RouteHint)", StringComparison.Ordinal) || runtimeSurfaceDocuments.Contains("CultMesh.RouteRecord(binding.RouteKind, binding.RouteDescription)", StringComparison.Ordinal) || runtimeSurfaceBuilder.Contains("ParseRouteKind(", StringComparison.Ordinal) || runtimeSurfaceDocuments.Contains("ParseRouteKind(", StringComparison.Ordinal)) @@ -916,20 +916,11 @@ static void RequireSharedEvePackagesImportedFromEveRepo(string root) "AetheriaRuntimeEveSurfaceAdapter is dead conversion chaff; runtime surface lowering belongs on AetheriaRuntimeSurfaceDocuments."); } - var surfaceCommandDocuments = string.Join( - "\n", - runtimeSurfaceDocuments, - playerSettingsSurfaceDocuments, - catalogSurfaceDocuments, - operationsSurfaceDocuments); if (!runtimeCultCacheDocumentStore.Contains("CultMesh.OperationBindingRecord(command.Operation)", StringComparison.Ordinal) || !runtimeCultCacheDocumentStore.Contains("CultMesh.OperationBindingRecord(", StringComparison.Ordinal) || !runtimeCultCacheDocumentStore.Contains("routeDescription).ToBinding()", StringComparison.Ordinal) || - !runtimeSurfaceDocuments.Contains("CultMesh.OperationBindingRecord(", StringComparison.Ordinal) || - !runtimeSurfaceDocuments.Contains("command.SchemaId", StringComparison.Ordinal) || !runtimeSurfaceDocuments.Contains("public static GameCult.Mesh.EveSurfaceDocument ToPortableSurface(AetheriaRuntimeSurfaceDocument document)", StringComparison.Ordinal) || !runtimeSurfaceDocuments.Contains("new GameCult.Mesh.EveSurfaceCommandTemplate(command.Operation)", StringComparison.Ordinal) || - !surfaceCommandDocuments.Contains("CultMesh.OperationBindingRecord(", StringComparison.Ordinal) || runtimeCultCacheDocumentStore.Contains("new CultMeshOperationBindingDescriptor(", StringComparison.Ordinal) || runtimeSurfaceDocuments.Contains("new CultMeshOperationBindingDescriptor(", StringComparison.Ordinal)) { @@ -1015,45 +1006,31 @@ static void RequirePackageSerializerBoundary(string root) throw new InvalidOperationException($"Cannot verify package serializer boundary; missing path: {packageRuntimeRoot}"); } - var allowedFiles = new HashSet(StringComparer.Ordinal) + var allowedSerializerExecutionFiles = new HashSet(StringComparer.Ordinal) { "AetheriaRuntimeCatalogStore.cs", "AetheriaRuntimeClientTargetStore.cs", "AetheriaRuntimeCultCacheDocumentStore.cs", "AetheriaRuntimeVerseClient.cs", - "AetheriaRuntimeSnapshotDocuments.cs", - "AetheriaRuntimeEveCommandDocument.cs", - "AetheriaRuntimeEveSurfaceState.cs", - "AetheriaRuntimeDaemonDocuments.cs", - "AetheriaRuntimeDaemonSoaDocuments.cs", - "AetheriaRuntimeRtsViewportDocuments.cs", - "AetheriaRuntimeAssetDocuments.cs", - "AetheriaRuntimeRenderSplatDocuments.cs", - "AetheriaRuntimeSettingsDocuments.cs", - "AetheriaRuntimeSurfaceDocuments.cs", - "AetheriaRuntimeInventoryDropdownSurfaceDocuments.cs", - "AetheriaRuntimeStarbridgeDocuments.cs", - "AetheriaRuntimeStarbridgePlayerSeatDocuments.cs", - "AetheriaRuntimeVerseAuthorityPolicy.cs" + "AetheriaRuntimeSnapshotDocuments.cs" }; - var serializerSymbols = new[] + var serializerExecutionSymbols = new[] { - "MessagePack", "MessagePackObject", "MessagePackSerializer", "MessagePackReader", "MessagePackWriter", - "IMessagePackFormatter", - "[Union(", - "[Key(" + "IMessagePackFormatter" }; var hits = Directory.EnumerateFiles(packageRuntimeRoot, "*.cs", SearchOption.AllDirectories) - .Where(path => !allowedFiles.Contains(Path.GetFileName(path))) + .Where(path => !allowedSerializerExecutionFiles.Contains(Path.GetFileName(path))) .SelectMany(path => File.ReadLines(path) .Select((line, index) => new { Path = path, LineNumber = index + 1, Line = line })) - .Where(line => serializerSymbols.Any(symbol => line.Line.Contains(symbol, StringComparison.Ordinal))) + .Where(line => serializerExecutionSymbols + .Where(symbol => symbol != "MessagePackObject") + .Any(symbol => line.Line.Contains(symbol, StringComparison.Ordinal))) .Select(line => $"{Path.GetRelativePath(root, line.Path)}:{line.LineNumber}: {line.Line.Trim()}") .Take(10) .ToArray(); @@ -1061,7 +1038,7 @@ static void RequirePackageSerializerBoundary(string root) if (hits.Length > 0) { throw new InvalidOperationException( - "Package serializer symbols escaped the named CultCache transport boundary: " + + "Package serializer execution escaped the named CultCache transport boundary: " + string.Join("; ", hits)); } } @@ -3367,11 +3344,10 @@ static void RequireEveRuntimeBootstrap(string root) { "private string surfaceId = AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId", "ReadDaemonSurface(stateBoot)", - ".RuntimeState(stateBoot, \"unity-eve-surface-presenter\")", ".EveSurfaceDocument(surfaceId)", "?.Reactive()", - "AetheriaUnityRuntimeClientProvider.EveSurfaceCultMeshStateRefResolver(", - "CultMeshReactiveDocument", + "AetheriaEveRuntimeUnityHooks.TryCreateStateRefResolver(", + "CultMeshReactiveDocument", "ResolveReactiveDaemonSurfaceState(", "DisposeReactiveSurfaceState()", "AetheriaRuntimeSurfaceDocuments.ToEveSurfaceDocument(", @@ -3781,8 +3757,9 @@ static void RequireMainMenuSettingsCommands(string root) var requiredMainMenuSymbols = new[] { - "AetheriaRuntimeMainMenuSurfaceBuilder.BuildPlayerSettingsShell(", - "ResolvePlayerSettings(CurrentStateBoot())", + "ResolveMainMenuSurface(AetheriaRuntimeMainMenuCommands.PlayerSettingsShellSurfaceId)", + ".RuntimeState(stateBoot, \"unity-main-menu\")", + ".MainMenuSurface(surfaceId, CanOpenRuntimeInputScreen(), InGame)", "AetheriaEveUnitySurfaceHost.RenderRuntime(", "AetheriaRuntimeMainMenuCommandKind.PlayerSettingsCommand", "SendKnownAetheriaEveCommand(request, \"player-settings\")" @@ -3873,11 +3850,11 @@ static void RequireMainMenuSettingsShellUsesEveSurface(string root) var requiredSymbols = new[] { "RenderMenuSurface(", - "AetheriaRuntimeMainMenuSurfaceBuilder.BuildSettings(", - "AetheriaRuntimeMainMenuSurfaceBuilder.BuildPlayerSettingsShell(", - "AetheriaRuntimeMainMenuSurfaceBuilder.BuildVerseSettingsShell(", - "AetheriaRuntimeClientTargetSurfaceBuilder.Build(", - "AetheriaRuntimeMainMenuSurfaceBuilder.BuildInputSettings(", + "ResolveMainMenuSurface(AetheriaRuntimeMainMenuCommands.SettingsSurfaceId)", + "ResolveMainMenuSurface(AetheriaRuntimeMainMenuCommands.InputSettingsSurfaceId)", + "ResolveMainMenuSurface(AetheriaRuntimeMainMenuCommands.PlayerSettingsShellSurfaceId)", + "ResolveMainMenuSurface(AetheriaRuntimeMainMenuCommands.VerseSettingsShellSurfaceId)", + ".MainMenuSurface(surfaceId, CanOpenRuntimeInputScreen(), InGame)", "HandleSettingsSurfaceCommand(", "HandleVerseSettingsSurfaceCommand(", "HandleInputSettingsSurfaceCommand(", @@ -3888,7 +3865,6 @@ static void RequireMainMenuSettingsShellUsesEveSurface(string root) "AetheriaRuntimeMainMenuCommandKind.BackToMain", "AetheriaRuntimeMainMenuCommandKind.BackToSettings", "AetheriaRuntimeMainMenuCommandKind.OpenRuntimeInputScreen", - "ResolvePlayerSettings(", "AetheriaEveUnitySurfaceHost.RenderRuntime(", "AetheriaEveUnitySurfaceHost.Hide(_menuSurfaceDocument)" }; @@ -4017,7 +3993,8 @@ static void RequireMainMenuRootUsesEveSurface(string root) var mainMenuSurfaceBuilder = File.ReadAllText(mainMenuSurfaceBuilderPath); var requiredSymbols = new[] { - "AetheriaRuntimeMainMenuSurfaceBuilder.BuildRoot(", + "ResolveMainMenuSurface(AetheriaRuntimeMainMenuCommands.RootSurfaceId)", + ".MainMenuSurface(surfaceId, CanOpenRuntimeInputScreen(), InGame)", "AetheriaRuntimeMainMenuSurfaceCommands.TryRead(request, out var command)", "AetheriaRuntimeMainMenuCommandKind.ContinueRun", "AetheriaRuntimeMainMenuCommandKind.NewGame", @@ -4025,8 +4002,6 @@ static void RequireMainMenuRootUsesEveSurface(string root) "AetheriaRuntimeMainMenuCommandKind.Quit", "HandleMainSurfaceCommand(", "ResolveSectorMap(stateBoot)", - "ResolveVerseHostSettings(stateBoot)", - "ResolvePlayerSettings(stateBoot)", "HideMenuSurface();" }; @@ -4041,6 +4016,13 @@ static void RequireMainMenuRootUsesEveSurface(string root) string.Join(", ", missingSymbols)); } + if (!mainMenuSurfaceBuilder.Contains("AetheriaRuntimeMainMenuSurfaceBuilder", StringComparison.Ordinal) || + !mainMenuSurfaceBuilder.Contains("public static AetheriaRuntimeSurfaceDocument BuildRoot(", StringComparison.Ordinal)) + { + throw new InvalidOperationException( + "Shared runtime main-menu surface builder no longer owns the root shell composition."); + } + var forbiddenSymbols = new[] { "PanelPrototype", @@ -4299,8 +4281,8 @@ static void RequireMainMenuInputSettingsDelegateToRuntimeScreen(string root) "SetRuntimeInputScreenShell(Func canOpenRuntimeInputScreen, Action openRuntimeInputScreen)", "CanOpenRuntimeInputScreen()", "TryOpenRuntimeInputScreen()", - "AetheriaRuntimeMainMenuSurfaceBuilder.BuildInputSettings(", - "ResolvePlayerSettings(stateBoot)", + "ResolveMainMenuSurface(AetheriaRuntimeMainMenuCommands.InputSettingsSurfaceId)", + ".MainMenuSurface(surfaceId, CanOpenRuntimeInputScreen(), InGame)", "_canOpenRuntimeInputScreen?.Invoke() == true", "_openRuntimeInputScreen?.Invoke();" }; @@ -5055,7 +5037,9 @@ static void RequireRuntimeMenuTabsUseEveSurface(string root) "public static class AetheriaEveUnitySurfaceHost", "public static UIDocument Render(", "new EveUiToolkitSurfaceLowerer(new EveUiToolkitSurfaceOptions(embeddedDocumentResolver))", - "shell.Add(lowerer.Lower(surface, commandHandler))" + "lowerer.Lower(surface, commandHandler)", + "shell.Add(lowered)", + "root.Add(lowered)" }; var missingHostSymbols = requiredHostSymbols @@ -5375,7 +5359,7 @@ static void RequireInventoryCargoItemDetailsUseEveSurface(string root) "Packages", "org.gamecult.aetheria.state", "Runtime", - "AetheriaRuntimePlayerSettingsSurfaceBuilder.cs"); + "AetheriaRuntimeSurfaceDocuments.cs"); var daemonItemStatQueriesPath = Path.Combine( root, "Packages", @@ -5501,32 +5485,41 @@ static void RequireInventoryCargoItemDetailsUseEveSurface(string root) "InventoryMenu must project current item stats through shared daemon item-stat queries instead of direct Unity ItemManager stat authority."); } - if (!surfaceDocument.Contains("public static class AetheriaRuntimeSurfaceStateRefs", StringComparison.Ordinal) || - !surfaceDocument.Contains("public const string Source = \"stateRef\"", StringComparison.Ordinal) || - !surfaceDocument.Contains("public const string Value = \"valueRef\"", StringComparison.Ordinal) || - !daemonItemStatQueries.Contains("public const string StateRefPrefix = \"aetheria.state/items\"", StringComparison.Ordinal) || - !daemonItemStatQueries.Contains("public static string ItemStatRef(", StringComparison.Ordinal) || - !daemonItemStatQueries.Contains("public static bool TryReadItemStatRef(", StringComparison.Ordinal) || - !daemonItemStatQueries.Contains("public string ValueRef =>", StringComparison.Ordinal) || - !unityProject.Contains("AetheriaRuntimeDaemonItemStatQueries.cs", StringComparison.Ordinal) || - !eveUnitySurfaceHost.Contains("CultMeshStateRefResolver stateRefResolver", StringComparison.Ordinal) || - !eveUnitySurfaceHost.Contains("ContainsStateRefs(surface)", StringComparison.Ordinal) || - !eveUnitySurfaceHost.Contains("prop.Key.EndsWith(\"Ref\", StringComparison.Ordinal)", StringComparison.Ordinal) || - !eveUnitySurfaceHost.Contains("CreateDefaultStateRefResolver()", StringComparison.Ordinal) || - !eveUnitySurfaceHost.Contains("AetheriaUnityRuntimeClientProvider", StringComparison.Ordinal) || - !eveUnitySurfaceHost.Contains("AetheriaUnityRuntimeClientProvider.EveSurfaceCultMeshStateRefResolver(", StringComparison.Ordinal) || - !runtimeSurfaceDocuments.Contains("public static EveSurfaceDocument ResolveStateRefs(", StringComparison.Ordinal) || - !runtimeSurfaceDocuments.Contains("ResolvePropRefs(props, resolveStateRef)", StringComparison.Ordinal) || - !runtimeSurfaceDocuments.Contains("ResolvePropRef(props, AetheriaRuntimeSurfaceStateRefs.Source, \"value\", resolveStateRef)", StringComparison.Ordinal) || - !runtimeSurfaceDocuments.Contains("IsStatePointerProp(prop.Key)", StringComparison.Ordinal) || - !runtimeSurfaceDocuments.Contains("ResolvePointerValueKey(refProp.Key)", StringComparison.Ordinal) || - !cargoItemSurfaceBuilder.Contains("public string ValueRef { get; }", StringComparison.Ordinal) || - !cargoItemSurfaceBuilder.Contains("props.Add(AetheriaRuntimeSurfaceStateRefs.ValueRef(valueRef))", StringComparison.Ordinal) || - !equippedItemSurfaceBuilder.Contains("public string ValueRef { get; }", StringComparison.Ordinal) || - !equippedItemSurfaceBuilder.Contains("props.Add(AetheriaRuntimeSurfaceStateRefs.ValueRef(valueRef))", StringComparison.Ordinal)) + var stateRefRequiredSymbols = new[] + { + ("AetheriaRuntimeSurfaceDocuments.cs", surfaceDocument, "public static class AetheriaRuntimeSurfaceStateRefs"), + ("AetheriaRuntimeSurfaceDocuments.cs", surfaceDocument, "public const string Source = \"stateRef\""), + ("AetheriaRuntimeSurfaceDocuments.cs", surfaceDocument, "public const string Value = \"valueRef\""), + ("AetheriaRuntimeDaemonItemStatQueries.cs", daemonItemStatQueries, "public const string StateRefPrefix = \"aetheria.state/items\""), + ("AetheriaRuntimeDaemonItemStatQueries.cs", daemonItemStatQueries, "public static string ItemStatRef("), + ("AetheriaRuntimeDaemonItemStatQueries.cs", daemonItemStatQueries, "public static bool TryReadItemStatRef("), + ("AetheriaRuntimeDaemonItemStatQueries.cs", daemonItemStatQueries, "public string ValueRef =>"), + ("GameCult.Aetheria.State.Unity.csproj", unityProject, "AetheriaRuntimeDaemonItemStatQueries.cs"), + ("AetheriaEveUnitySurfaceHost.cs", eveUnitySurfaceHost, "CultMeshStateRefResolver stateRefResolver"), + ("AetheriaEveUnitySurfaceHost.cs", eveUnitySurfaceHost, "ContainsStateRefs(surface)"), + ("AetheriaEveUnitySurfaceHost.cs", eveUnitySurfaceHost, "prop.Key.EndsWith(\"Ref\", StringComparison.Ordinal)"), + ("AetheriaEveUnitySurfaceHost.cs", eveUnitySurfaceHost, "CreateDefaultStateRefResolver()"), + ("AetheriaEveUnitySurfaceHost.cs", eveUnitySurfaceHost, "AetheriaEveRuntimeUnityHooks"), + ("AetheriaEveUnitySurfaceHost.cs", eveUnitySurfaceHost, "TryCreateDefaultStateRefResolver()"), + ("AetheriaRuntimeSurfaceDocuments.cs", runtimeSurfaceDocuments, "public static EveUiSurfaceDocument ResolveStateRefs("), + ("AetheriaRuntimeSurfaceDocuments.cs", runtimeSurfaceDocuments, "ResolvePropRefs(props, resolveStateRef)"), + ("AetheriaRuntimeSurfaceDocuments.cs", runtimeSurfaceDocuments, "ResolvePropRef(props, AetheriaRuntimeSurfaceStateRefs.Source, \"value\", resolveStateRef)"), + ("AetheriaRuntimeSurfaceDocuments.cs", runtimeSurfaceDocuments, "IsStatePointerProp(prop.Key)"), + ("AetheriaRuntimeSurfaceDocuments.cs", runtimeSurfaceDocuments, "ResolvePointerValueKey(refProp.Key)"), + ("AetheriaRuntimeCargoItemDetailsSurfaceBuilder.cs", cargoItemSurfaceBuilder, "public string ValueRef { get; }"), + ("AetheriaRuntimeCargoItemDetailsSurfaceBuilder.cs", cargoItemSurfaceBuilder, "props.Add(AetheriaRuntimeSurfaceStateRefs.ValueRef(valueRef))"), + ("AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.cs", equippedItemSurfaceBuilder, "public string ValueRef { get; }"), + ("AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.cs", equippedItemSurfaceBuilder, "props.Add(AetheriaRuntimeSurfaceStateRefs.ValueRef(valueRef))") + }; + var missingStateRefSymbols = stateRefRequiredSymbols + .Where(symbol => !symbol.Item2.Contains(symbol.Item3, StringComparison.Ordinal)) + .Select(symbol => $"{symbol.Item1}: {symbol.Item3}") + .ToArray(); + if (missingStateRefSymbols.Length > 0) { throw new InvalidOperationException( - "Eve/CultUI item stat surfaces must expose typed daemon state refs that the UI runtime can resolve."); + "Eve/CultUI item stat surfaces must expose typed daemon state refs that the UI runtime can resolve: " + + string.Join(", ", missingStateRefSymbols)); } var forbiddenSymbols = new[] @@ -6719,7 +6712,7 @@ static void RequireInventoryDropdownUseEveSurface(string root) "AetheriaRuntimeInventoryDropdownCommandKind.Close", "AetheriaRuntimeInventoryDropdownCommandKind.Select", "TryResolveDropdownSelection(request, command.Command, out var selection)", - "AetheriaRuntimeInventoryDropdownSurfaceCommands.TryReadSelection(command, selectionKey, out selection)", + "PayloadValue(request, \"selectionKind\")", "AetheriaRuntimeInventoryDropdownSelectionKind.EntityBay", "AetheriaRuntimeInventoryDropdownSelectionKind.Loadout", "selection.EntityKey", @@ -7191,15 +7184,33 @@ static void RequirePlayerSettingsEveSurface(string root) "Player settings Eve surface document should pass typed settings directly into the shared builder, not repack them into a shadow surface state."); } - var bridge = File.Exists(bridgePath) - ? File.ReadAllText(bridgePath) - : throw new InvalidOperationException("Player settings Eve command bridge is missing."); - var provider = File.Exists(providerPath) - ? File.ReadAllText(providerPath) - : throw new InvalidOperationException("Player settings provider advertisement projector is missing."); - var daemonHost = File.Exists(daemonHostPath) - ? File.ReadAllText(daemonHostPath) - : throw new InvalidOperationException("Aetheria.State.Daemon program is missing."); + var runtimeVerseClientPath = Path.Combine( + root, + "Packages", + "org.gamecult.aetheria.state", + "Runtime", + "AetheriaRuntimeVerseClient.cs"); + var runtimeEveCommandClientPath = Path.Combine( + root, + "Packages", + "org.gamecult.aetheria.state", + "Runtime", + "AetheriaRuntimeEveCommandClient.cs"); + var runtimeUiPath = Path.Combine( + root, + "Packages", + "org.gamecult.aetheria.state", + "Runtime", + "AetheriaUi.cs"); + var runtimeVerseClient = File.Exists(runtimeVerseClientPath) + ? File.ReadAllText(runtimeVerseClientPath) + : throw new InvalidOperationException("Managed runtime Verse client is missing."); + var runtimeEveCommandClient = File.Exists(runtimeEveCommandClientPath) + ? File.ReadAllText(runtimeEveCommandClientPath) + : throw new InvalidOperationException("Managed runtime Eve command client is missing."); + var runtimeUi = File.Exists(runtimeUiPath) + ? File.ReadAllText(runtimeUiPath) + : throw new InvalidOperationException("Managed runtime UI command facade is missing."); var sharedCommands = File.Exists(sharedCommandsPath) ? File.ReadAllText(sharedCommandsPath) : throw new InvalidOperationException("Shared player-settings Eve command contract is missing."); @@ -7207,38 +7218,28 @@ static void RequirePlayerSettingsEveSurface(string root) ? File.ReadAllText(surfaceBuilderPath) : throw new InvalidOperationException("Shared player-settings Eve surface builder is missing."); - if (!bridge.Contains("AcceptedPlayerSettingsCommands", StringComparison.Ordinal) || - !bridge.Contains("ExecutePlayerSettingsCommandAsync", StringComparison.Ordinal) || - !bridge.Contains("MutableDocument(AetheriaStateNode.PlayerSettingsSurfaceKey)", StringComparison.Ordinal) || - !bridge.Contains(".ReplaceAsync(AetheriaEveSurfaceDocuments.BuildPlayerSettingsSurface", StringComparison.Ordinal) || - !bridge.Contains("SetPlayerName", StringComparison.Ordinal) || - !bridge.Contains("command.PlayerSettings.PlayerName", StringComparison.Ordinal)) + if (!runtimeUi.Contains("public async Task SurfaceCommandAsync(", StringComparison.Ordinal) || + !runtimeUi.Contains(".SubmitKnownSurfaceCommandAsync(request, clientId, flush)", StringComparison.Ordinal) || + !runtimeVerseClient.Contains("SubmitKnownSurfaceCommandAsync(", StringComparison.Ordinal) || + !runtimeVerseClient.Contains("AetheriaRuntimeEveCommandClient.TryCreateKnownSurfaceCommand(request, out var envelope)", StringComparison.Ordinal) || + !runtimeVerseClient.Contains("Database.PutAsync(AetheriaRuntimeVerseRecordKeys.EveCommand(command.CommandId), command)", StringComparison.Ordinal) || + !runtimeEveCommandClient.Contains("AetheriaRuntimePlayerSettingsCommands.SurfaceId", StringComparison.Ordinal) || + !runtimeEveCommandClient.Contains("AetheriaRuntimePlayerSettingsCommands.IsKnown(command)", StringComparison.Ordinal) || + !runtimeEveCommandClient.Contains("CreatePlayerSettingsCommand(CommandKindForSurface(request), request, clientId)", StringComparison.Ordinal) || + !runtimeEveCommandClient.Contains("playerSettings: ReadPlayerSettingsBody(request)", StringComparison.Ordinal) || + !runtimeEveCommandClient.Contains("invocation: request.Operation", StringComparison.Ordinal) || + !runtimeEveCommandClient.Contains("payload: request.Payload", StringComparison.Ordinal)) { throw new InvalidOperationException( - "Eve command bridge no longer owns the typed player-settings surface mutation path."); + "Managed Eve command path no longer submits typed player-settings surface commands through CultMesh."); } - if (!provider.Contains("SurfaceId = PlayerSettingsSurfaceId", StringComparison.Ordinal) || - !provider.Contains("Key = PlayerSettingsSurfaceKey", StringComparison.Ordinal) || - !provider.Contains("AetheriaRuntimePlayerSettingsCommands.Refresh", StringComparison.Ordinal)) + if ((File.Exists(bridgePath) && File.ReadAllText(bridgePath).Contains("MutableDocument", StringComparison.Ordinal)) || + (File.Exists(daemonHostPath) && File.ReadAllText(daemonHostPath).Contains("MutableDocument", StringComparison.Ordinal)) || + runtimeVerseClient.Contains("EveSurfaceState", StringComparison.Ordinal)) { throw new InvalidOperationException( - "Provider advertisement no longer publishes the player-settings Eve surface and commands."); - } - - if (!daemonHost.Contains("MutableDocument(AetheriaStateNode.PlayerSettingsSurfaceKey)", StringComparison.Ordinal) || - !daemonHost.Contains(".ReplaceAsync(AetheriaEveSurfaceDocuments.BuildPlayerSettingsSurface", StringComparison.Ordinal) || - !daemonHost.Contains("AetheriaEveSurfaceDocuments.BuildPlayerSettingsSurface", StringComparison.Ordinal)) - { - throw new InvalidOperationException( - "Aetheria.State.Daemon no longer republishes the provider-owned player-settings Eve surface."); - } - - if (bridge.Contains("PlayerSettingsSurface()", StringComparison.Ordinal) || - daemonHost.Contains("PlayerSettingsSurface()", StringComparison.Ordinal)) - { - throw new InvalidOperationException( - "Player-settings Eve publication still uses named AetheriaStateNode surface helpers instead of generic mutable typed documents."); + "Player-settings Eve command path still depends on local EveSurfaceState publication instead of managed CultMesh command documents."); } if (!sharedCommands.Contains("SurfaceId = \"aetheria.player_settings\"", StringComparison.Ordinal) || @@ -8072,9 +8073,8 @@ static void RequireUnitySharedDocumentAccessorErgonomics(string root) { "AetheriaUnityRuntimeClientProvider", ".RuntimeState(stateBoot, \"unity-main-menu\")", - ".SectorMap", - ".PlayerSettings", - ".VerseHostSettings", + "ResolveMainMenuSurface(string surfaceId)", + ".MainMenuSurface(surfaceId, CanOpenRuntimeInputScreen(), InGame)", ".Latest()", "private void OnDestroy()" }; @@ -8084,7 +8084,7 @@ static void RequireUnitySharedDocumentAccessorErgonomics(string root) if (missingMainMenuSharedDocumentSymbols.Length > 0) { throw new InvalidOperationException( - "MainMenu should sample sector, player, and Verse host state through a managed typed Aetheria runtime state handle: " + + "MainMenu should sample daemon-published menu surfaces through a managed typed Aetheria runtime state handle: " + string.Join(", ", missingMainMenuSharedDocumentSymbols)); } @@ -8717,7 +8717,7 @@ static void RequireAetheriaManagedStateAccessorsCoverDomainDocuments(string root "public CultMeshDocumentHandle Catalog { get; }", "public CultMeshDocumentHandle PlayerSettings { get; }", "public static bool TryResolveEveSurface(", - "public CultMeshDocumentHandle? EveSurfaceDocument(", + "public CultMeshDocumentHandle? EveSurfaceDocument(", "public CultMeshDocumentHandle RtsViewport(", "public CultMeshDocumentHandle ObjectsViewport(", "public CultMeshDocumentHandle GravityViewport(", @@ -9444,6 +9444,7 @@ static void RequireClientTargetBootAuthority(string root) var mainMenuSurfaceBuilderPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeMainMenuSurfaceBuilder.cs"); var bootstrapPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.eve-runtime", "Runtime", "AetheriaEveRuntimeBootstrap.cs"); var presenterPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.eve-runtime", "Runtime", "AetheriaEveSurfacePresenter.cs"); + var unityEveRuntimeHooksPath = Path.Combine(root, "Assets", "Scripts", "Gameplay", "AetheriaUnityEveRuntimeHooks.cs"); var actionGameManagerPath = Path.Combine(root, "Assets", "Scripts", "Gameplay", "ActionGameManager.cs"); var gameplayBootShellPath = Path.Combine(root, "Assets", "Scripts", "Gameplay", "AetheriaUnityGameplayBootShell.cs"); var mainMenuPath = Path.Combine(root, "Assets", "Scripts", "UI", "MainMenu.cs"); @@ -9461,6 +9462,7 @@ static void RequireClientTargetBootAuthority(string root) mainMenuSurfaceBuilderPath, bootstrapPath, presenterPath, + unityEveRuntimeHooksPath, actionGameManagerPath, gameplayBootShellPath, mainMenuPath @@ -9488,6 +9490,7 @@ static void RequireClientTargetBootAuthority(string root) var mainMenuSurfaceBuilder = File.ReadAllText(mainMenuSurfaceBuilderPath); var bootstrap = File.ReadAllText(bootstrapPath); var presenter = File.ReadAllText(presenterPath); + var unityEveRuntimeHooks = File.ReadAllText(unityEveRuntimeHooksPath); var actionGameManager = File.ReadAllText(actionGameManagerPath); var gameplayBootShell = File.ReadAllText(gameplayBootShellPath); var mainMenu = File.ReadAllText(mainMenuPath); @@ -9821,8 +9824,8 @@ static void RequireClientTargetBootAuthority(string root) var requiredPresenterSymbols = new[] { - "AetheriaRuntimeStateBoot.Inspect(", - "AetheriaUnityRuntimePaths.GameDataDirectory", + "ResolveStateBoot()", + "AetheriaEveRuntimeUnityHooks.RequireStateBoot(", "!stateBoot.SupportsLocalStateFileRead", "stateBoot.StateFileExists" }; @@ -9836,6 +9839,13 @@ static void RequireClientTargetBootAuthority(string root) string.Join(", ", missingPresenterSymbols)); } + if (!unityEveRuntimeHooks.Contains("AetheriaRuntimeStateBoot.Inspect(", StringComparison.Ordinal) || + !unityEveRuntimeHooks.Contains("AetheriaUnityRuntimePaths.GameDataDirectory", StringComparison.Ordinal)) + { + throw new InvalidOperationException( + "Aetheria Eve runtime hooks no longer own Unity client-target boot resolution."); + } + if (bootstrap.Contains("StatePathEnvironmentVariable", StringComparison.Ordinal) || bootstrap.Contains("presenter.StateFilePathOverride =", StringComparison.Ordinal)) { @@ -9851,26 +9861,21 @@ static void RequireClientTargetBootAuthority(string root) ".RuntimeState(stateBoot, \"unity-main-menu\")", ".SectorMap", ".Latest()", - "ResolveVerseHostSettings(AetheriaRuntimeStateBootReport stateBoot)", - ".VerseHostSettings", + "ResolveMainMenuSurface(", + ".MainMenuSurface(surfaceId, CanOpenRuntimeInputScreen(), InGame)", "AetheriaState.At(AetheriaUnityRuntimePaths.GameDataDirectory)", ".ClientTarget", "RequestClientTargetCommand(request)", - "AetheriaRuntimeClientTargetSurfaceCommands.TryRequest(", - "ResolvePlayerSettings(AetheriaRuntimeStateBootReport stateBoot)", - ".PlayerSettings", - "AetheriaRuntimeClientTargetSurfaceBuilder.Build(", - "AetheriaRuntimeMainMenuSurfaceBuilder.BuildRoot(", - "AetheriaRuntimeMainMenuSurfaceBuilder.BuildSettings(", - "AetheriaRuntimeMainMenuSurfaceBuilder.BuildInputSettings(" + "AetheriaRuntimeClientTargetSurfaceCommands.TryRequest(" }; var requiredMainMenuBuilderSymbols = new[] { "private static AetheriaRuntimeSurfaceDocument BuildRoot(", "var verseLabel = VerseLabel(verseTitle, verseId)", - "\"Client Target\"", - "\"Transport\"", - "\"Target Source\"" + "\"Verse\"", + "\"Target\"", + "\"Daemon\"", + "\"Transport\"" }; var missingMainMenuSymbols = requiredMainMenuSymbols .Where(symbol => !mainMenu.Contains(symbol, StringComparison.Ordinal)) @@ -10351,10 +10356,10 @@ static void RequireVerseSettingsShellAndBridge(string root) var requiredMainMenuSymbols = new[] { "AetheriaRuntimeMainMenuCommandKind.ShowVerseSettings", - "ShowVerseSettingsSurface()", + "ShowVerseSettingsSurface(", "HandleVerseSettingsSurfaceCommand(EveSurfaceCommandRequest request)", - "AetheriaRuntimeMainMenuSurfaceBuilder.BuildVerseSettingsShell(", - "AetheriaRuntimeClientTargetSurfaceBuilder.Build(", + "ResolveMainMenuSurface(AetheriaRuntimeMainMenuCommands.VerseSettingsShellSurfaceId)", + ".MainMenuSurface(surfaceId, CanOpenRuntimeInputScreen(), InGame)", "AetheriaRuntimeMainMenuSurfaceCommands.TryRead(request, out var command)", "AetheriaRuntimeMainMenuCommandKind.ClientTargetCommand", "AetheriaRuntimeMainMenuCommandKind.VerseHostCommand", @@ -11737,10 +11742,10 @@ static void RequireDaemonVersePublication(string root) "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonProviderAdvertisement)", "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonHealth)", "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonCommandBoundary)", - "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface)", - "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonGameTuiSurface)", - "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonEditorSurface)", - "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonEditorTuiSurface)", + "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface)", + "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonGameTuiSurface)", + "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonEditorSurface)", + "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonEditorTuiSurface)", "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.StarbridgeSessionSummary)", ".ReplaceAsync(result.Frame)", ".ReplaceAsync(result.SoaView)", @@ -11760,8 +11765,8 @@ static void RequireDaemonVersePublication(string root) "node.MutableDocument(AetheriaStateNode.EveCommandAcceptanceStatusKey)", "node.MutableDocument(AetheriaStateNode.RuntimeSessionKey(options.DaemonId))", "node.MutableDocument(AetheriaStateNode.PlayerSettingsKey).ReadAsync()", - "node.MutableDocument(AetheriaStateNode.OperationsSurfaceKey)", - "node.MutableDocument(AetheriaStateNode.PlayerSettingsSurfaceKey)", + "node.MutableDocument(AetheriaStateNode.OperationsSurfaceKey)", + "node.MutableDocument(AetheriaStateNode.PlayerSettingsSurfaceKey)", "node.MutableDocument(AetheriaStateNode.ProviderAdvertisementSurfaceKey)", "AetheriaEveSurfaceDocuments.BuildProviderAdvertisement(verseHost, node.StatePath, updatedAtUtc)", "AetheriaEveSurfaceDocuments.BuildOperationsSurface(eveStatus, verseHost, runtimeSession)", @@ -12196,13 +12201,13 @@ static void RequireDaemonVersePublication(string root) "AetheriaClient control submission did not appear as a typed daemon state record.", "AetheriaClient UI submission did not appear as a typed Eve state record.", "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonFrameLatest)", - "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface)", - ".ReplaceAsync(AetheriaRuntimeSurfaceDocuments.ToEveSurfaceState(daemonGameSurface))", + "node.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface)", + ".ReplaceAsync(AetheriaRuntimeSurfaceDocuments.ToPortableSurface(daemonGameSurface))", "reopened.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonProviderAdvertisement)", "reopened.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonHealth)", "reopened.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonCommandBoundary)", "reopened.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonFrameLatest)", - "reopened.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface)", + "reopened.MutableDocument(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface)", "DaemonGameSurfaceKey", "DaemonGameTuiSurfaceKey", "DaemonEditorSurfaceKey", @@ -12323,20 +12328,34 @@ static void RequireDaemonVersePublication(string root) static void RequireUnityRuntimeCatalogClientUsesManagedDocument(string root) { - var clientPath = Path.Combine(root, "Aetheria.State.Unity", "AetheriaRuntimeCatalogClient.cs"); + var clientPath = Path.Combine( + root, + "Packages", + "org.gamecult.aetheria.state", + "Runtime", + "AetheriaClientState.cs"); + var verseClientPath = Path.Combine( + root, + "Packages", + "org.gamecult.aetheria.state", + "Runtime", + "AetheriaRuntimeVerseClient.cs"); var mapperPath = Path.Combine(root, "Aetheria.State.Unity", "AetheriaRuntimeCatalogSnapshotMapper.cs"); var client = File.Exists(clientPath) ? File.ReadAllText(clientPath) - : throw new InvalidOperationException("Cannot verify Unity runtime catalog client; AetheriaRuntimeCatalogClient.cs is missing."); + : throw new InvalidOperationException("Cannot verify managed Unity runtime catalog client; AetheriaClientState.cs is missing."); + var verseClient = File.Exists(verseClientPath) + ? File.ReadAllText(verseClientPath) + : throw new InvalidOperationException("Cannot verify managed Unity runtime catalog client; AetheriaRuntimeVerseClient.cs is missing."); var requiredSymbols = new[] { - "\"aetheria-unity-runtime-catalog\",", - "enableDurableShardLogs: false", - "public AetheriaRuntimeCatalogSnapshot ReadCatalog()", - "return _node.RuntimeCatalog().Latest();", - "public EveSurfaceState? ReadCatalogSurface()", - "return _node.CatalogSurface().Latest();" + "using MeshEveSurfaceDocument = GameCult.Mesh.EveSurfaceDocument;", + "CultMeshDocumentHandle catalog", + "public CultMeshDocumentHandle Catalog", + "public CultMeshDocumentHandle? EveSurfaceDocument(", + "AetheriaClientEveSurface.Game => GameSurface", + "AetheriaClientEveSurface.Editor => EditorSurface" }; var missingSymbols = requiredSymbols .Where(symbol => !client.Contains(symbol, StringComparison.Ordinal)) @@ -12348,8 +12367,26 @@ static void RequireUnityRuntimeCatalogClientUsesManagedDocument(string root) string.Join(", ", missingSymbols)); } + var requiredVerseClientSymbols = new[] + { + "BootstrapCatalogDocument(", + "Document(", + "AetheriaRuntimeVerseRecordKeys.DaemonGameSurface", + "AetheriaRuntimeVerseRecordKeys.DaemonEditorSurface" + }; + var missingVerseClientSymbols = requiredVerseClientSymbols + .Where(symbol => !verseClient.Contains(symbol, StringComparison.Ordinal)) + .ToArray(); + if (missingVerseClientSymbols.Length > 0) + { + throw new InvalidOperationException( + "Runtime Verse client no longer exposes managed catalog/Eve surface document handles: " + + string.Join(", ", missingVerseClientSymbols)); + } + var forbiddenSymbols = new[] { + "EveSurfaceState", "_node.ReadCatalog", "_node.GetCatalogSurfaceAsync()", "ReadCatalogSurfaceAsync(", @@ -12564,18 +12601,18 @@ static void RequireAetheriaRuntimeVerseClientContract(string root) "AetheriaRuntimeLoadoutTemplatesDocument", "StarbridgeSummaryAsync", "CultMeshReactiveDocument? managedDaemonFrame = null;", - "managedDaemonFrame = state.DaemonFrame.Reactive();", - "managedCatalog = state.Catalog.Reactive();", - "managedLoadoutTemplates = state.LoadoutTemplates.Reactive();", + "managedDaemonFrame ??= latestFrameDocument.Reactive();", + "managedCatalog ??= catalogDocument.Reactive();", + "managedLoadoutTemplates ??= loadoutTemplatesDocument.Reactive();", "managedPlayerSettings = state.PlayerSettings.Reactive();", - "managedStarbridgeScenario = state.StarbridgeScenario.Reactive();", - "managedStarbridgeSession = state.StarbridgeSession.Reactive();", + "managedStarbridgeScenario ??= starbridgeScenarioDocument.Reactive();", + "managedStarbridgeSession ??= starbridgeSessionDocument.Reactive();", "AetheriaRuntimeDaemonFrameDocument RequireManagedFrame()", "RequireManagedFrame()", "RequireManagedCatalog()", "RequireManagedLoadoutTemplates().Templates", - "managedStarbridgeScenario?.Current", - "managedStarbridgeSession?.Current", + "return managedStarbridgeScenario.Current;", + "return managedStarbridgeSession.Current;", "BootstrapCatalogDocument(", "CatalogBootstrapSource(", "BootstrapRuntimeCatalog", @@ -12673,12 +12710,7 @@ static void RequireAetheriaRuntimeVerseClientContract(string root) client.Contains("state.ObserveCatalog()", StringComparison.Ordinal) || client.Contains("state.ObserveLoadoutTemplates()", StringComparison.Ordinal) || client.Contains("state.Starbridge.ObserveScenario()", StringComparison.Ordinal) || - client.Contains("state.Starbridge.ObserveSession()", StringComparison.Ordinal) || - client.Contains("catalogDocument.Reactive()", StringComparison.Ordinal) || - client.Contains("loadoutTemplatesDocument.Reactive()", StringComparison.Ordinal) || - client.Contains("starbridgeScenarioDocument.Reactive()", StringComparison.Ordinal) || - client.Contains("starbridgeSessionDocument.Reactive()", StringComparison.Ordinal) || - client.Contains("latestFrameDocument.Reactive()", StringComparison.Ordinal)) + client.Contains("state.Starbridge.ObserveSession()", StringComparison.Ordinal)) { throw new InvalidOperationException( "Aetheria Verse client derived documents must sample directly owned named reactive typed documents instead of an input/session wrapper."); @@ -12735,14 +12767,13 @@ static void RequireAetheriaRuntimeVerseClientContract(string root) "CultMeshReactiveDocument? _eveStateRefHealth", "CultMeshReactiveDocument? _eveStateRefCommandBoundary", "CultMeshReactiveDocument? _eveStateRefCatalog", - "_eveStateRefFrame ??= DaemonFrame.Reactive()", - "_eveStateRefHealth ??= Health.Reactive()", - "_eveStateRefCommandBoundary ??= CommandBoundary.Reactive()", - "_eveStateRefCatalog ??= Catalog.Reactive()", - "() => _eveStateRefFrame.Current", - "() => _eveStateRefHealth.Current", - "() => _eveStateRefCommandBoundary.Current", - "() => _eveStateRefCatalog.Current", + "() => ReadOptionalReactive(ref _eveStateRefFrame, DaemonFrame)", + "() => ReadOptionalReactive(ref _eveStateRefHealth, Health)", + "() => ReadOptionalReactive(ref _eveStateRefCommandBoundary, CommandBoundary)", + "() => ReadOptionalReactive(ref _eveStateRefCatalog, Catalog)", + "private static TDocument? ReadOptionalReactive(", + "reactive ??= handle.Reactive()", + "return reactive.Current", "public void Dispose()", "_eveStateRefFrame?.Dispose()", "_eveStateRefHealth?.Dispose()", @@ -13500,41 +13531,41 @@ static void RequireMainMenuVerseHostDocumentAccess(string root) var requiredMainMenuSymbols = new[] { - "ResolveVerseHostSettings(AetheriaRuntimeStateBootReport stateBoot)", "AetheriaUnityRuntimeClientProvider", ".RuntimeState(stateBoot, \"unity-main-menu\")", - ".VerseHostSettings", + ".MainMenuSurface(surfaceId, CanOpenRuntimeInputScreen(), InGame)", ".Latest()", - "AetheriaRuntimeClientTargetSurfaceBuilder.Build(", - "AetheriaRuntimeMainMenuSurfaceBuilder.BuildRoot(" + "ResolveMainMenuSurface(" }; var requiredBuilderSymbols = new[] { - "\"Client Target\"", - "\"Transport\"", - "\"Target Source\"", - "\"Verse\"", - "\"Visibility\"", - "\"CultMesh\"", - "The client target chooses which Verse it follows; game truth belongs to the daemon serving" + "public static AetheriaRuntimeSurfaceDocument BuildRoot(", + "AetheriaRuntimeStateBootReport stateBoot", + "AetheriaRuntimeVerseHostSettingsDocument verseHost", + "verseHost?.Title ?? stateBoot.Title", + "verseHost?.VerseId ?? stateBoot.VerseId", + "verseHost?.Visibility ?? \"unknown\"", + "verseHost?.CultMeshAddress ?? stateBoot.CultMeshAddress", + ".TitleSubtitle(\"AETHERIA\", \"TERMINUS\")", + ".Metric(\"Verse\", verseLabel)", + ".Metric(\"Target\", targetLine)", + ".Metric(\"Daemon\", daemonLine)", + ".Metric(\"Transport\", transportLine)", + "private static string VerseLabel(", + "private static string TargetLine(", + "\"No daemon frame\"", + "\"Run {daemonRunId} / frame {daemonFrameId}\"" }; var requiredClientTargetBuilderSymbols = new[] { "Build(", "AetheriaRuntimeStateBootReport stateBoot", - "AetheriaRuntimeVerseHostSettingsDocument verseHost", - "stateBoot.FailureMessage", - "stateBoot.DiscoveryEndpoints", - "stateBoot.DiscoveredVerses", - "stateBoot.LastDiscoveryAtUtc", - "stateBoot.LastDiscoveryError", - "stateBoot.ReplicaStateFilePath", - "stateBoot.LastReplicaSyncAtUtc", - "stateBoot.LastReplicaSyncError", - "var hostTitle = verseHost?.Title ?? targetTitle", - "var hostVerseId = verseHost?.VerseId ?? targetVerseId", - "var hostVisibility = verseHost?.Visibility ?? \"unknown\"", - "var hostCultMeshAddress = verseHost?.CultMeshAddress ?? targetCultMeshAddress" + "\"Transport\"", + "\"Target Source\"", + "\"Verse\"", + "\"Visibility\"", + "\"CultMesh\"", + "Client target edits are local. Visibility changes append provider-owned Eve requests" }; var missingMainMenuSymbols = requiredMainMenuSymbols .Where(symbol => !mainMenu.Contains(symbol, StringComparison.Ordinal)) @@ -13570,13 +13601,15 @@ static void RequireMainMenuVerseHostDocumentAccess(string root) string.Join(", ", missingClientTargetBuilderSymbols)); } - if (mainMenu.Contains("AetheriaRuntimeMainMenuSurfaceBuilder.ProjectVerseSettings(", StringComparison.Ordinal) || + if (mainMenu.Contains("AetheriaRuntimeMainMenuSurfaceBuilder.BuildRoot(", StringComparison.Ordinal) || + mainMenu.Contains("AetheriaRuntimeClientTargetSurfaceBuilder.Build(", StringComparison.Ordinal) || + mainMenu.Contains("AetheriaRuntimeMainMenuSurfaceBuilder.ProjectVerseSettings(", StringComparison.Ordinal) || mainMenuSurfaceBuilder.Contains("ProjectVerseSettings(", StringComparison.Ordinal) || mainMenu.Contains("new AetheriaRuntimeClientTargetSurfaceState(", StringComparison.Ordinal) || mainMenuSurfaceBuilder.Contains("new AetheriaRuntimeClientTargetSurfaceState(", StringComparison.Ordinal)) { throw new InvalidOperationException( - "Main-menu Verse state must come from typed documents through AetheriaRuntimeClientTargetSurfaceBuilder; do not reintroduce menu-local client-target state shaping."); + "Unity MainMenu must consume daemon-published main-menu surfaces instead of reintroducing menu-local client-target state shaping."); } } @@ -16682,16 +16715,18 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) var requiredSurfaceDocumentSymbols = new[] { "public static class AetheriaRuntimeSurfaceDocuments", - "public static EveSurfaceDocument ToEveSurfaceDocument(AetheriaRuntimeSurfaceDocument document)", - "public static EveSurfaceDocument ResolveStateRefs(", + "public static GameCult.Mesh.EveSurfaceDocument ToPortableSurface(AetheriaRuntimeSurfaceDocument document)", + "public static EveUiSurfaceDocument ToEveSurfaceDocument(AetheriaRuntimeSurfaceDocument document)", + "public static EveUiSurfaceDocument ToEveSurfaceDocument(GameCult.Mesh.EveSurfaceDocument document)", + "public static EveUiSurfaceDocument ResolveStateRefs(", "CultMeshStateRefResolver? stateRefResolver", "ResolvePropRefs(props, resolveStateRef)", "ResolvePropRef(props, AetheriaRuntimeSurfaceStateRefs.Source, \"value\", resolveStateRef)", "IsStatePointerProp(prop.Key)", "ResolvePointerValueKey(refProp.Key)", - "public static EveSurfaceDocument EmptySurface(string surfaceId)", - "new EveSurfaceDocument(", - "new EveSurfaceComponent(" + "public static EveUiSurfaceDocument EmptySurface(string surfaceId)", + "new EveUiSurfaceDocument(", + "new EveUiSurfaceComponent(" }; var missingSurfaceDocumentSymbols = requiredSurfaceDocumentSymbols .Where(symbol => !runtimeSurfaceDocuments.Contains(symbol, StringComparison.Ordinal)) @@ -16977,7 +17012,8 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) var missingProviderClientAccess = providerOwnedClientAccessSources .Where(pair => - !pair.Value.Contains("AetheriaUnityRuntimeClientProvider", StringComparison.Ordinal)) + !pair.Value.Contains("AetheriaUnityRuntimeClientProvider", StringComparison.Ordinal) && + !pair.Value.Contains("AetheriaEveRuntimeUnityHooks", StringComparison.Ordinal)) .Select(pair => pair.Key) .ToArray(); if (missingProviderClientAccess.Length > 0) @@ -17023,10 +17059,11 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) "public CultMeshDocumentHandle AuthorityPolicy { get; }", "public CultMeshDocumentHandle DaemonFrame { get; }", "public CultMeshDocumentHandle DaemonSoaView { get; }", - "public CultMeshDocumentHandle GameSurface { get; }", - "public CultMeshDocumentHandle GameTuiSurface { get; }", - "public CultMeshDocumentHandle EditorSurface { get; }", - "public CultMeshDocumentHandle EditorTuiSurface { get; }", + "using MeshEveSurfaceDocument = GameCult.Mesh.EveSurfaceDocument;", + "public CultMeshDocumentHandle GameSurface { get; }", + "public CultMeshDocumentHandle GameTuiSurface { get; }", + "public CultMeshDocumentHandle EditorSurface { get; }", + "public CultMeshDocumentHandle EditorTuiSurface { get; }", "public CultMeshDocumentHandle Catalog { get; }", "public CultMeshDocumentHandle LoadoutTemplates { get; }", "public CultMeshDocumentHandle PlayerSettings { get; }", @@ -17420,11 +17457,9 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) } if (!mainMenu.Contains("AetheriaUnityRuntimeClientProvider", StringComparison.Ordinal) || - !mainMenu.Contains("ResolveSectorMap(AetheriaRuntimeStateBootReport stateBoot)", StringComparison.Ordinal) || + !mainMenu.Contains("ResolveMainMenuSurface(string surfaceId)", StringComparison.Ordinal) || !mainMenu.Contains(".RuntimeState(stateBoot, \"unity-main-menu\")", StringComparison.Ordinal) || - !mainMenu.Contains(".SectorMap", StringComparison.Ordinal) || - !mainMenu.Contains(".PlayerSettings", StringComparison.Ordinal) || - !mainMenu.Contains(".VerseHostSettings", StringComparison.Ordinal) || + !mainMenu.Contains(".MainMenuSurface(surfaceId, CanOpenRuntimeInputScreen(), InGame)", StringComparison.Ordinal) || !mainMenu.Contains(".Latest()", StringComparison.Ordinal)) { throw new InvalidOperationException( @@ -17513,7 +17548,7 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) string.Join(", ", mainMenuReaderHits)); } - if (!eveSurfacePresenter.Contains(".RuntimeState(stateBoot, \"unity-eve-surface-presenter\")", StringComparison.Ordinal) || + if (!eveSurfacePresenter.Contains(".RequireRuntimeState(stateBoot, \"unity-eve-surface-presenter\")", StringComparison.Ordinal) || !eveSurfacePresenter.Contains(".EveSurfaceDocument(surfaceId)", StringComparison.Ordinal) || !eveSurfacePresenter.Contains("?.Reactive()", StringComparison.Ordinal) || !eveSurfacePresenter.Contains("ReadDaemonSurface(stateBoot)", StringComparison.Ordinal)) @@ -17522,8 +17557,8 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root) "Aetheria Eve surface presenter must grab the provider RuntimeState and read the daemon surface through AetheriaClientState reactive typed documents."); } - if (!eveSurfacePresenter.Contains("AetheriaUnityRuntimeClientProvider.EveSurfaceCultMeshStateRefResolver(", StringComparison.Ordinal) || - !eveUnitySurfaceHost.Contains("AetheriaUnityRuntimeClientProvider.EveSurfaceCultMeshStateRefResolver(", StringComparison.Ordinal)) + if (!eveSurfacePresenter.Contains("AetheriaEveRuntimeUnityHooks.TryCreateStateRefResolver(", StringComparison.Ordinal) || + !eveUnitySurfaceHost.Contains("AetheriaEveRuntimeUnityHooks.TryCreateDefaultStateRefResolver()", StringComparison.Ordinal)) { throw new InvalidOperationException( "Unity Eve surface lowering must resolve provider state refs through provider-native managed AetheriaClientState documents."); diff --git a/Assets/Scripts/UI/MainMenu.cs b/Assets/Scripts/UI/MainMenu.cs index 7bf687329..867de8251 100644 --- a/Assets/Scripts/UI/MainMenu.cs +++ b/Assets/Scripts/UI/MainMenu.cs @@ -16,20 +16,12 @@ public class MainMenu : MonoBehaviour public GameSettings Settings; public ConfirmationDialog Dialog; public bool InGame; - public float FadeTime = 0.5f; - public float FadeDistance = 512f; - public float FadeAlphaExponent = 2f; - public float FadePositionExponent = 2f; public float HoverSpacing = 8f; public float HoverAnimationDuration = 0.16f; - private UIDocument _currentMenuSurfaceDocument; - private UIDocument _nextMenuSurfaceDocument; + private UIDocument _menuSurfaceDocument; private Func _canOpenRuntimeInputScreen; private Action _openRuntimeInputScreen; - private bool _fadeFromRight; - private bool _fading; - private float _fadeLerp; private readonly List _hoverButtons = new List(); private readonly AetheriaEveUnitySurfaceChrome _menuSurfaceChrome = new AetheriaEveUnitySurfaceChrome { @@ -51,7 +43,6 @@ public class MainMenu : MonoBehaviour void Update() { - UpdateMenuFade(); UpdateHoverButtons(); } @@ -219,30 +210,16 @@ public class MainMenu : MonoBehaviour Action commandHandler, bool animateFromRight) { - var initialRender = _currentMenuSurfaceDocument == null; - var targetDocument = initialRender ? _currentMenuSurfaceDocument : _nextMenuSurfaceDocument; - targetDocument = AetheriaEveUnitySurfaceHost.RenderRuntime( + _menuSurfaceDocument = AetheriaEveUnitySurfaceHost.RenderRuntime( transform, - targetDocument, - initialRender ? "Aetheria Menu Surface" : "Aetheria Menu Surface Transition", + _menuSurfaceDocument, + "Aetheria Menu Surface", document, commandHandler, _menuSurfaceChrome, - sortingOrder: initialRender ? 1000 : 1001); + sortingOrder: 1000); - ApplyMenuStyles(targetDocument.rootVisualElement, IsRootMainMenu(document)); - SetDocumentTransition(targetDocument, initialRender ? 0f : (animateFromRight ? FadeDistance : -FadeDistance), initialRender ? 1f : 0f); - - if (initialRender) - { - _currentMenuSurfaceDocument = targetDocument; - return; - } - - _nextMenuSurfaceDocument = targetDocument; - _fadeFromRight = animateFromRight; - _fadeLerp = 0f; - _fading = true; + ApplyMenuStyles(_menuSurfaceDocument.rootVisualElement, IsRootMainMenu(document)); } private static bool IsRootMainMenu(AetheriaRuntimeSurfaceDocument document) @@ -253,46 +230,6 @@ public class MainMenu : MonoBehaviour StringComparison.Ordinal); } - private void UpdateMenuFade() - { - if (!_fading) - return; - - _fadeLerp += Time.unscaledDeltaTime / Mathf.Max(0.01f, FadeTime); - var t = Mathf.Clamp01(_fadeLerp); - var outgoing = Mathf.Pow(t, FadePositionExponent); - var incoming = Mathf.Pow(1f - t, FadePositionExponent); - var direction = _fadeFromRight ? 1f : -1f; - - SetDocumentTransition( - _currentMenuSurfaceDocument, - -direction * FadeDistance * outgoing, - Mathf.Pow(1f - t, FadeAlphaExponent)); - SetDocumentTransition( - _nextMenuSurfaceDocument, - direction * FadeDistance * incoming, - Mathf.Pow(t, FadeAlphaExponent)); - - if (_fadeLerp <= 1f) - return; - - _fading = false; - AetheriaEveUnitySurfaceHost.Hide(_currentMenuSurfaceDocument); - var previous = _currentMenuSurfaceDocument; - _currentMenuSurfaceDocument = _nextMenuSurfaceDocument; - _nextMenuSurfaceDocument = previous; - SetDocumentTransition(_currentMenuSurfaceDocument, 0f, 1f); - } - - private static void SetDocumentTransition(UIDocument document, float x, float opacity) - { - if (document?.rootVisualElement == null) - return; - - document.rootVisualElement.style.translate = new Translate(new Length(x, LengthUnit.Pixel), 0f, 0f); - document.rootVisualElement.style.opacity = opacity; - } - private void UpdateHoverButtons() { for (var i = _hoverButtons.Count - 1; i >= 0; i--) @@ -689,8 +626,7 @@ public class MainMenu : MonoBehaviour private void HideMenuSurface() { - AetheriaEveUnitySurfaceHost.Hide(_currentMenuSurfaceDocument); - AetheriaEveUnitySurfaceHost.Hide(_nextMenuSurfaceDocument); + AetheriaEveUnitySurfaceHost.Hide(_menuSurfaceDocument); } public void SetRuntimeInputScreenShell(Func canOpenRuntimeInputScreen, Action openRuntimeInputScreen) @@ -777,16 +713,10 @@ public class MainMenu : MonoBehaviour private void OnDestroy() { - if (_currentMenuSurfaceDocument != null) + if (_menuSurfaceDocument != null) { - Destroy(_currentMenuSurfaceDocument.gameObject); - _currentMenuSurfaceDocument = null; - } - - if (_nextMenuSurfaceDocument != null) - { - Destroy(_nextMenuSurfaceDocument.gameObject); - _nextMenuSurfaceDocument = null; + Destroy(_menuSurfaceDocument.gameObject); + _menuSurfaceDocument = null; } } diff --git a/GameData/aetheria-world.cc b/GameData/aetheria-world.cc index dc4173233..1785936ed 100644 Binary files a/GameData/aetheria-world.cc and b/GameData/aetheria-world.cc differ diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs index 513746afa..1e48ff63c 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeCatalogSnapshot.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using GameCult.Caching; +using MessagePack; #nullable enable @@ -11,10 +12,11 @@ namespace GameCult.Aetheria.State.Verse public sealed class AetheriaRuntimeCatalogSnapshot { public const string SchemaId = "gamecult.aetheria.runtime_catalog.v1"; + public const string DocumentName = "aetheria.runtime_catalog"; - private readonly Dictionary _itemsByKey; - private readonly Dictionary _corporationsByKey; - private readonly Dictionary _nameFilesByKey; + public AetheriaRuntimeCatalogSnapshot() + { + } public AetheriaRuntimeCatalogSnapshot( AetheriaRuntimeCatalogItem[] items, @@ -22,39 +24,39 @@ namespace GameCult.Aetheria.State.Verse AetheriaRuntimeNameFile[] nameFiles, AetheriaRuntimeTradeValueSettings? tradeValueSettings = null) { - Items = items; - Corporations = corporations; - NameFiles = nameFiles; + Items = items ?? Array.Empty(); + Corporations = corporations ?? Array.Empty(); + NameFiles = nameFiles ?? Array.Empty(); TradeValueSettings = tradeValueSettings ?? AetheriaRuntimeTradeValueSettings.Default; - TradeItems = items.Where(item => item.Price > 0).ToArray(); - EquipmentItems = items.Where(item => !string.IsNullOrWhiteSpace(item.HardpointType)).ToArray(); - - _itemsByKey = items - .Where(item => !string.IsNullOrWhiteSpace(item.ItemKey)) - .ToDictionary(item => item.ItemKey, StringComparer.OrdinalIgnoreCase); - _corporationsByKey = corporations - .Where(corporation => !string.IsNullOrWhiteSpace(corporation.CorporationKey)) - .ToDictionary(corporation => corporation.CorporationKey, StringComparer.OrdinalIgnoreCase); - _nameFilesByKey = nameFiles - .Where(nameFile => !string.IsNullOrWhiteSpace(nameFile.NameFileKey)) - .ToDictionary(nameFile => nameFile.NameFileKey, StringComparer.OrdinalIgnoreCase); } - public IReadOnlyList Items { get; } + [Key(0)] + [CultName] + public string CatalogId { get; set; } = DocumentName; - public IReadOnlyList TradeItems { get; } + [Key(1)] + public IReadOnlyList Items { get; set; } = Array.Empty(); - public IReadOnlyList EquipmentItems { get; } + [IgnoreMember] + public IReadOnlyList TradeItems => + Items.Where(item => item.Price > 0).ToArray(); - public IReadOnlyList Corporations { get; } + [IgnoreMember] + public IReadOnlyList EquipmentItems => + Items.Where(item => !string.IsNullOrWhiteSpace(item.HardpointType)).ToArray(); - public IReadOnlyList NameFiles { get; } + [Key(2)] + public IReadOnlyList Corporations { get; set; } = Array.Empty(); - public AetheriaRuntimeTradeValueSettings TradeValueSettings { get; } + [Key(3)] + public IReadOnlyList NameFiles { get; set; } = Array.Empty(); + + [Key(4)] + public AetheriaRuntimeTradeValueSettings TradeValueSettings { get; set; } = AetheriaRuntimeTradeValueSettings.Default; public AetheriaRuntimeCatalogItem? FindItem(string itemKey) { - return TryGet(_itemsByKey, itemKey); + return TryGet(Items, itemKey, item => item.ItemKey); } public AetheriaRuntimeCatalogItem? FindItem(T? item, Func itemKey) where T : class @@ -67,12 +69,12 @@ namespace GameCult.Aetheria.State.Verse public AetheriaRuntimeCorporation? FindCorporation(string corporationKey) { - return TryGet(_corporationsByKey, corporationKey); + return TryGet(Corporations, corporationKey, corporation => corporation.CorporationKey); } public AetheriaRuntimeNameFile? FindNameFile(string nameFileKey) { - return TryGet(_nameFilesByKey, nameFileKey); + return TryGet(NameFiles, nameFileKey, nameFile => nameFile.NameFileKey); } public IEnumerable FindItemsByBehavior(string behaviorKind) @@ -99,9 +101,11 @@ namespace GameCult.Aetheria.State.Verse return FindNameFile(corporation.GeonameFileKey); } - private static T? TryGet(IReadOnlyDictionary dictionary, string key) where T : class + private static T? TryGet(IEnumerable values, string key, Func getKey) where T : class { - return string.IsNullOrWhiteSpace(key) ? null : dictionary.TryGetValue(key, out var value) ? value : null; + return string.IsNullOrWhiteSpace(key) + ? null + : values.FirstOrDefault(value => string.Equals(getKey(value), key, StringComparison.OrdinalIgnoreCase)); } } @@ -109,6 +113,11 @@ namespace GameCult.Aetheria.State.Verse public sealed class AetheriaRuntimeLoadoutTemplatesDocument { public const string SchemaId = "gamecult.aetheria.loadout_templates.v1"; + public const string DocumentName = "aetheria.loadout_templates"; + + public AetheriaRuntimeLoadoutTemplatesDocument() + { + } public AetheriaRuntimeLoadoutTemplatesDocument( IReadOnlyList? templates = null) @@ -116,9 +125,16 @@ namespace GameCult.Aetheria.State.Verse Templates = templates ?? Array.Empty(); } - public IReadOnlyList Templates { get; } + [Key(0)] + [CultName] + public string CatalogId { get; set; } = DocumentName; + + [Key(1)] + public IReadOnlyList Templates { get; set; } = + Array.Empty(); } + [MessagePackObject(true)] public sealed class AetheriaRuntimeCatalogItem { public AetheriaRuntimeCatalogItem( @@ -221,54 +237,54 @@ namespace GameCult.Aetheria.State.Verse CompoundCommodityCategory = compoundCommodityCategory; } - public string ItemKey { get; } - public string Name { get; } - public string Category { get; } - public string Description { get; } - public string ManufacturerKey { get; } - public int Price { get; } - public double Mass { get; } - public double SpecificHeat { get; } - public double Conductivity { get; } - public double Volume { get; } - public int ShapeWidth { get; } - public int ShapeHeight { get; } - public int OccupiedCells { get; } - public IReadOnlyList ShapeCells { get; } - public int InteriorShapeWidth { get; } - public int InteriorShapeHeight { get; } - public int InteriorOccupiedCells { get; } - public IReadOnlyList InteriorShapeCells { get; } - public IReadOnlyList Hardpoints { get; } - public IReadOnlyList BehaviorPayloads { get; } - public string HardpointType { get; } - public string HullType { get; } - public IReadOnlyList BehaviorKinds { get; } - public int MaxStack { get; } - public bool Stackable { get; } - public double Duration { get; } - public double Durability { get; } - public string WeaponRange { get; } - public string WeaponCaliber { get; } - public string WeaponType { get; } - public string WeaponFireTypes { get; } - public string WeaponModifiers { get; } - public double MinimumTemperature { get; } - public double MaximumTemperature { get; } - public IReadOnlyList ThermalPerformanceCurveKeys { get; } - public string HullPrefab { get; } - public double ThermalResilience { get; } - public double HullGridOffset { get; } - public double HullArmor { get; } - public double HullDrag { get; } - public bool HullCanTow { get; } - public int DockingMaxSizeX { get; } - public int DockingMaxSizeY { get; } - public string ActionBarIcon { get; } - public IReadOnlyList AudioStats { get; } - public IReadOnlyList EffectivenessCurveKeys { get; } - public string SimpleCommodityCategory { get; } - public string CompoundCommodityCategory { get; } + public string ItemKey { get; set; } + public string Name { get; set; } + public string Category { get; set; } + public string Description { get; set; } + public string ManufacturerKey { get; set; } + public int Price { get; set; } + public double Mass { get; set; } + public double SpecificHeat { get; set; } + public double Conductivity { get; set; } + public double Volume { get; set; } + public int ShapeWidth { get; set; } + public int ShapeHeight { get; set; } + public int OccupiedCells { get; set; } + public IReadOnlyList ShapeCells { get; set; } + public int InteriorShapeWidth { get; set; } + public int InteriorShapeHeight { get; set; } + public int InteriorOccupiedCells { get; set; } + public IReadOnlyList InteriorShapeCells { get; set; } + public IReadOnlyList Hardpoints { get; set; } + public IReadOnlyList BehaviorPayloads { get; set; } + public string HardpointType { get; set; } + public string HullType { get; set; } + public IReadOnlyList BehaviorKinds { get; set; } + public int MaxStack { get; set; } + public bool Stackable { get; set; } + public double Duration { get; set; } + public double Durability { get; set; } + public string WeaponRange { get; set; } + public string WeaponCaliber { get; set; } + public string WeaponType { get; set; } + public string WeaponFireTypes { get; set; } + public string WeaponModifiers { get; set; } + public double MinimumTemperature { get; set; } + public double MaximumTemperature { get; set; } + public IReadOnlyList ThermalPerformanceCurveKeys { get; set; } + public string HullPrefab { get; set; } + public double ThermalResilience { get; set; } + public double HullGridOffset { get; set; } + public double HullArmor { get; set; } + public double HullDrag { get; set; } + public bool HullCanTow { get; set; } + public int DockingMaxSizeX { get; set; } + public int DockingMaxSizeY { get; set; } + public string ActionBarIcon { get; set; } + public IReadOnlyList AudioStats { get; set; } + public IReadOnlyList EffectivenessCurveKeys { get; set; } + public string SimpleCommodityCategory { get; set; } + public string CompoundCommodityCategory { get; set; } public bool TryGetHardpointType(out TEnum hardpointType) where TEnum : struct { @@ -292,6 +308,7 @@ namespace GameCult.Aetheria.State.Verse } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeAudioStat { public AetheriaRuntimeAudioStat(uint parameter, AetheriaRuntimePerformanceStat stat) @@ -300,10 +317,11 @@ namespace GameCult.Aetheria.State.Verse Stat = stat; } - public uint Parameter { get; } - public AetheriaRuntimePerformanceStat Stat { get; } + public uint Parameter { get; set; } + public AetheriaRuntimePerformanceStat Stat { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimePerformanceStat { public AetheriaRuntimePerformanceStat( @@ -322,14 +340,15 @@ namespace GameCult.Aetheria.State.Verse Recipe = recipe; } - public double Min { get; } - public double Max { get; } - public double HeatExponentMultiplier { get; } - public double DurabilityExponentMultiplier { get; } - public double QualityExponent { get; } - public AetheriaRuntimeStatRecipe? Recipe { get; } + public double Min { get; set; } + public double Max { get; set; } + public double HeatExponentMultiplier { get; set; } + public double DurabilityExponentMultiplier { get; set; } + public double QualityExponent { get; set; } + public AetheriaRuntimeStatRecipe? Recipe { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeStatRecipe { public AetheriaRuntimeStatRecipe(double baseValue, IReadOnlyList modifiers) @@ -338,10 +357,11 @@ namespace GameCult.Aetheria.State.Verse Modifiers = modifiers ?? Array.Empty(); } - public double BaseValue { get; } - public IReadOnlyList Modifiers { get; } + public double BaseValue { get; set; } + public IReadOnlyList Modifiers { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeStatRecipeModifier { public AetheriaRuntimeStatRecipeModifier( @@ -358,13 +378,14 @@ namespace GameCult.Aetheria.State.Verse Enabled = enabled; } - public string Condition { get; } - public string Operation { get; } - public double Amount { get; } - public IReadOnlyList CurveKeys { get; } - public bool Enabled { get; } + public string Condition { get; set; } + public string Operation { get; set; } + public double Amount { get; set; } + public IReadOnlyList CurveKeys { get; set; } + public bool Enabled { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeCurveKey { public AetheriaRuntimeCurveKey(double time, double value, double inTangent, double outTangent) @@ -375,12 +396,13 @@ namespace GameCult.Aetheria.State.Verse OutTangent = outTangent; } - public double Time { get; } - public double Value { get; } - public double InTangent { get; } - public double OutTangent { get; } + public double Time { get; set; } + public double Value { get; set; } + public double InTangent { get; set; } + public double OutTangent { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeShapeCell { public AetheriaRuntimeShapeCell(int x, int y) @@ -389,11 +411,12 @@ namespace GameCult.Aetheria.State.Verse Y = y; } - public int X { get; } + public int X { get; set; } - public int Y { get; } + public int Y { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeBehaviorPayload { public AetheriaRuntimeBehaviorPayload( @@ -408,15 +431,16 @@ namespace GameCult.Aetheria.State.Verse Fields = fields; } - public int UnionKey { get; } + public int UnionKey { get; set; } - public string Kind { get; } + public string Kind { get; set; } - public int Group { get; } + public int Group { get; set; } - public IReadOnlyList Fields { get; } + public IReadOnlyList Fields { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeBehaviorField { public AetheriaRuntimeBehaviorField(int key, AetheriaRuntimeBehaviorValue value) @@ -425,11 +449,12 @@ namespace GameCult.Aetheria.State.Verse Value = value; } - public int Key { get; } + public int Key { get; set; } - public AetheriaRuntimeBehaviorValue Value { get; } + public AetheriaRuntimeBehaviorValue Value { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeBehaviorMapEntry { public AetheriaRuntimeBehaviorMapEntry(string key, AetheriaRuntimeBehaviorValue value) @@ -438,11 +463,12 @@ namespace GameCult.Aetheria.State.Verse Value = value; } - public string Key { get; } + public string Key { get; set; } - public AetheriaRuntimeBehaviorValue Value { get; } + public AetheriaRuntimeBehaviorValue Value { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeBehaviorValue { public AetheriaRuntimeBehaviorValue( @@ -465,23 +491,24 @@ namespace GameCult.Aetheria.State.Verse MapEntries = mapEntries; } - public string Kind { get; } + public string Kind { get; set; } - public string StringValue { get; } + public string StringValue { get; set; } - public double NumberValue { get; } + public double NumberValue { get; set; } - public bool BoolValue { get; } + public bool BoolValue { get; set; } - public string LegacyIdValue { get; } + public string LegacyIdValue { get; set; } - public string ItemKeyValue { get; } + public string ItemKeyValue { get; set; } - public IReadOnlyList Children { get; } + public IReadOnlyList Children { get; set; } - public IReadOnlyList MapEntries { get; } + public IReadOnlyList MapEntries { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeHardpoint { public AetheriaRuntimeHardpoint( @@ -508,27 +535,28 @@ namespace GameCult.Aetheria.State.Verse Armor = armor; } - public string Type { get; } + public string Type { get; set; } - public int PositionX { get; } + public int PositionX { get; set; } - public int PositionY { get; } + public int PositionY { get; set; } - public int ShapeWidth { get; } + public int ShapeWidth { get; set; } - public int ShapeHeight { get; } + public int ShapeHeight { get; set; } - public int OccupiedCells { get; } + public int OccupiedCells { get; set; } - public IReadOnlyList ShapeCells { get; } + public IReadOnlyList ShapeCells { get; set; } - public string Transform { get; } + public string Transform { get; set; } - public string Rotation { get; } + public string Rotation { get; set; } - public double Armor { get; } + public double Armor { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeCorporation { public AetheriaRuntimeCorporation( @@ -553,17 +581,18 @@ namespace GameCult.Aetheria.State.Verse Allegiances = allegiances; } - public string CorporationKey { get; } - public string Name { get; } - public string ShortName { get; } - public string Description { get; } - public string GeonameFileKey { get; } - public string BossHullItemKey { get; } - public int InfluenceDistance { get; } - public int AllegianceCount { get; } - public IReadOnlyList Allegiances { get; } + public string CorporationKey { get; set; } + public string Name { get; set; } + public string ShortName { get; set; } + public string Description { get; set; } + public string GeonameFileKey { get; set; } + public string BossHullItemKey { get; set; } + public int InfluenceDistance { get; set; } + public int AllegianceCount { get; set; } + public IReadOnlyList Allegiances { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeCorporationAllegiance { public AetheriaRuntimeCorporationAllegiance(string corporationKey, double weight) @@ -572,10 +601,11 @@ namespace GameCult.Aetheria.State.Verse Weight = weight; } - public string CorporationKey { get; } - public double Weight { get; } + public string CorporationKey { get; set; } + public double Weight { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeNameFile { public AetheriaRuntimeNameFile( @@ -592,13 +622,14 @@ namespace GameCult.Aetheria.State.Verse Names = names; } - public string NameFileKey { get; } - public string Name { get; } - public int NameCount { get; } - public IReadOnlyList SampleNames { get; } - public IReadOnlyList Names { get; } + public string NameFileKey { get; set; } + public string Name { get; set; } + public int NameCount { get; set; } + public IReadOnlyList SampleNames { get; set; } + public IReadOnlyList Names { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimePlayerSettingsSnapshot { public AetheriaRuntimePlayerSettingsSnapshot( @@ -625,18 +656,19 @@ namespace GameCult.Aetheria.State.Verse ActionBarInputs = actionBarInputs; } - public string PlayerName { get; } - public bool TutorialPassed { get; } - public IReadOnlyList StoryFileHashes { get; } - public string TemperatureUnit { get; } - public int SignificantDigits { get; } - public double DefaultShutdownPerformance { get; } - public string NebulaQuality { get; } - public bool ShowAsteroidsInMinimap { get; } - public IReadOnlyList BindingOverrides { get; } - public IReadOnlyList ActionBarInputs { get; } + public string PlayerName { get; set; } + public bool TutorialPassed { get; set; } + public IReadOnlyList StoryFileHashes { get; set; } + public string TemperatureUnit { get; set; } + public int SignificantDigits { get; set; } + public double DefaultShutdownPerformance { get; set; } + public string NebulaQuality { get; set; } + public bool ShowAsteroidsInMinimap { get; set; } + public IReadOnlyList BindingOverrides { get; set; } + public IReadOnlyList ActionBarInputs { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeVerseHostSettingsSnapshot { public AetheriaRuntimeVerseHostSettingsSnapshot( @@ -661,17 +693,18 @@ namespace GameCult.Aetheria.State.Verse LastUpdatedAtUtc = lastUpdatedAtUtc; } - public string ServiceId { get; } - public string VerseId { get; } - public string RootVerse { get; } - public string CanonicalService { get; } - public string LocatedService { get; } - public string CultMeshAddress { get; } - public string Title { get; } - public string Visibility { get; } - public string LastUpdatedAtUtc { get; } + public string ServiceId { get; set; } + public string VerseId { get; set; } + public string RootVerse { get; set; } + public string CanonicalService { get; set; } + public string LocatedService { get; set; } + public string CultMeshAddress { get; set; } + public string Title { get; set; } + public string Visibility { get; set; } + public string LastUpdatedAtUtc { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeStoryFileHash { public AetheriaRuntimeStoryFileHash(string storyPath, string hash) @@ -680,10 +713,11 @@ namespace GameCult.Aetheria.State.Verse Hash = hash; } - public string StoryPath { get; } - public string Hash { get; } + public string StoryPath { get; set; } + public string Hash { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeInputBindingOverride { public AetheriaRuntimeInputBindingOverride(string actionName, int bindingIndex, string bindingPath) @@ -693,11 +727,12 @@ namespace GameCult.Aetheria.State.Verse BindingPath = bindingPath; } - public string ActionName { get; } - public int BindingIndex { get; } - public string BindingPath { get; } + public string ActionName { get; set; } + public int BindingIndex { get; set; } + public string BindingPath { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeLoadoutTemplateSnapshot { public AetheriaRuntimeLoadoutTemplateSnapshot( @@ -714,13 +749,14 @@ namespace GameCult.Aetheria.State.Verse UpdatedAtUtc = updatedAtUtc; } - public string Name { get; } - public string OwnerPlayerKey { get; } - public AetheriaRuntimeEntityLoadoutSnapshot RootEntity { get; } - public string CreatedAtUtc { get; } - public string UpdatedAtUtc { get; } + public string Name { get; set; } + public string OwnerPlayerKey { get; set; } + public AetheriaRuntimeEntityLoadoutSnapshot RootEntity { get; set; } + public string CreatedAtUtc { get; set; } + public string UpdatedAtUtc { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeEntityLoadoutSnapshot { public AetheriaRuntimeEntityLoadoutSnapshot( @@ -751,20 +787,21 @@ namespace GameCult.Aetheria.State.Verse Children = children; } - public string Name { get; } - public string Kind { get; } - public string FactionKey { get; } - public AetheriaRuntimeLoadoutItemSnapshot Hull { get; } - public IReadOnlyList Equipment { get; } - public IReadOnlyList CargoBays { get; } - public IReadOnlyList DockingBays { get; } - public IReadOnlyList CargoContents { get; } - public IReadOnlyList DockingBayContents { get; } - public IReadOnlyList DockingBayAssignments { get; } - public IReadOnlyList> WeaponGroups { get; } - public IReadOnlyList Children { get; } + public string Name { get; set; } + public string Kind { get; set; } + public string FactionKey { get; set; } + public AetheriaRuntimeLoadoutItemSnapshot Hull { get; set; } + public IReadOnlyList Equipment { get; set; } + public IReadOnlyList CargoBays { get; set; } + public IReadOnlyList DockingBays { get; set; } + public IReadOnlyList CargoContents { get; set; } + public IReadOnlyList DockingBayContents { get; set; } + public IReadOnlyList DockingBayAssignments { get; set; } + public IReadOnlyList> WeaponGroups { get; set; } + public IReadOnlyList Children { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeLoadoutItemSnapshot { public AetheriaRuntimeLoadoutItemSnapshot( @@ -785,15 +822,16 @@ namespace GameCult.Aetheria.State.Verse Temperature = temperature; } - public string ItemKey { get; } - public double Quality { get; } - public double Durability { get; } - public int Quantity { get; } - public bool Enabled { get; } - public bool OverrideShutdown { get; } - public double Temperature { get; } + public string ItemKey { get; set; } + public double Quality { get; set; } + public double Durability { get; set; } + public int Quantity { get; set; } + public bool Enabled { get; set; } + public bool OverrideShutdown { get; set; } + public double Temperature { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeLoadoutItemSlotSnapshot { public AetheriaRuntimeLoadoutItemSlotSnapshot(int x, int y, AetheriaRuntimeLoadoutItemSnapshot item) @@ -803,11 +841,12 @@ namespace GameCult.Aetheria.State.Verse Item = item; } - public int X { get; } - public int Y { get; } - public AetheriaRuntimeLoadoutItemSnapshot Item { get; } + public int X { get; set; } + public int Y { get; set; } + public AetheriaRuntimeLoadoutItemSnapshot Item { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeCargoBayLoadoutSnapshot { public AetheriaRuntimeCargoBayLoadoutSnapshot(IReadOnlyList items) @@ -815,9 +854,10 @@ namespace GameCult.Aetheria.State.Verse Items = items; } - public IReadOnlyList Items { get; } + public IReadOnlyList Items { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeEntitySnapshot { public AetheriaRuntimeEntitySnapshot( @@ -898,45 +938,46 @@ namespace GameCult.Aetheria.State.Verse ShutdownPerformance = shutdownPerformance; } - public string RecordKey { get; } - public int EntityIndex { get; } - public string Name { get; } - public string Kind { get; } - public double PositionX { get; } - public double PositionY { get; } - public double PositionZ { get; } - public double DirectionX { get; } - public double DirectionY { get; } - public string FactionKey { get; } - public string HullItemKey { get; } - public IReadOnlyList Equipment { get; } - public IReadOnlyList CargoBays { get; } - public IReadOnlyList DockingBays { get; } - public IReadOnlyList ChildEntityKeys { get; } - public IReadOnlyList> WeaponGroups { get; } - public IReadOnlyList StatGrids { get; } - public double VelocityX { get; } - public double VelocityY { get; } - public string TargetEntityKey { get; } - public bool IsActive { get; } - public bool HeatsinksEnabled { get; } - public bool OverrideShutdown { get; } - public double TractorPower { get; } - public double Heatstroke { get; } - public double Hypothermia { get; } - public IReadOnlyList ActiveConsumables { get; } - public IReadOnlyList BehaviorProgress { get; } - public IReadOnlyList WeaponStates { get; } - public IReadOnlyList BehaviorStates { get; } - public IReadOnlyList CargoContents { get; } - public IReadOnlyList DockingBayContents { get; } - public IReadOnlyList DockingBayAssignments { get; } - public double Visibility { get; } - public int VisibilitySourceCount { get; } - public IReadOnlyList Contacts { get; } - public double ShutdownPerformance { get; } + public string RecordKey { get; set; } + public int EntityIndex { get; set; } + public string Name { get; set; } + public string Kind { get; set; } + public double PositionX { get; set; } + public double PositionY { get; set; } + public double PositionZ { get; set; } + public double DirectionX { get; set; } + public double DirectionY { get; set; } + public string FactionKey { get; set; } + public string HullItemKey { get; set; } + public IReadOnlyList Equipment { get; set; } + public IReadOnlyList CargoBays { get; set; } + public IReadOnlyList DockingBays { get; set; } + public IReadOnlyList ChildEntityKeys { get; set; } + public IReadOnlyList> WeaponGroups { get; set; } + public IReadOnlyList StatGrids { get; set; } + public double VelocityX { get; set; } + public double VelocityY { get; set; } + public string TargetEntityKey { get; set; } + public bool IsActive { get; set; } + public bool HeatsinksEnabled { get; set; } + public bool OverrideShutdown { get; set; } + public double TractorPower { get; set; } + public double Heatstroke { get; set; } + public double Hypothermia { get; set; } + public IReadOnlyList ActiveConsumables { get; set; } + public IReadOnlyList BehaviorProgress { get; set; } + public IReadOnlyList WeaponStates { get; set; } + public IReadOnlyList BehaviorStates { get; set; } + public IReadOnlyList CargoContents { get; set; } + public IReadOnlyList DockingBayContents { get; set; } + public IReadOnlyList DockingBayAssignments { get; set; } + public double Visibility { get; set; } + public int VisibilitySourceCount { get; set; } + public IReadOnlyList Contacts { get; set; } + public double ShutdownPerformance { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeEntityContactSnapshot { public AetheriaRuntimeEntityContactSnapshot(string targetEntityKey, double infoGathered, bool hostile, bool visible) @@ -947,12 +988,13 @@ namespace GameCult.Aetheria.State.Verse Visible = visible; } - public string TargetEntityKey { get; } - public double InfoGathered { get; } - public bool Hostile { get; } - public bool Visible { get; } + public string TargetEntityKey { get; set; } + public double InfoGathered { get; set; } + public bool Hostile { get; set; } + public bool Visible { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeEntityItemSlotSnapshot { public AetheriaRuntimeEntityItemSlotSnapshot( @@ -977,17 +1019,18 @@ namespace GameCult.Aetheria.State.Verse Temperature = temperature; } - public int X { get; } - public int Y { get; } - public string ItemKey { get; } - public double Quality { get; } - public double Durability { get; } - public int Quantity { get; } - public bool Enabled { get; } - public bool OverrideShutdown { get; } - public double Temperature { get; } + public int X { get; set; } + public int Y { get; set; } + public string ItemKey { get; set; } + public double Quality { get; set; } + public double Durability { get; set; } + public int Quantity { get; set; } + public bool Enabled { get; set; } + public bool OverrideShutdown { get; set; } + public double Temperature { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeEntityStatGridSnapshot { public AetheriaRuntimeEntityStatGridSnapshot(string name, int width, int height, IReadOnlyList values) @@ -998,12 +1041,13 @@ namespace GameCult.Aetheria.State.Verse Values = values; } - public string Name { get; } - public int Width { get; } - public int Height { get; } - public IReadOnlyList Values { get; } + public string Name { get; set; } + public int Width { get; set; } + public int Height { get; set; } + public IReadOnlyList Values { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeActiveConsumableSnapshot { public AetheriaRuntimeActiveConsumableSnapshot(string itemKey, double quality, double remainingDuration, double duration) @@ -1014,12 +1058,13 @@ namespace GameCult.Aetheria.State.Verse Duration = duration; } - public string ItemKey { get; } - public double Quality { get; } - public double RemainingDuration { get; } - public double Duration { get; } + public string ItemKey { get; set; } + public double Quality { get; set; } + public double RemainingDuration { get; set; } + public double Duration { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeBehaviorProgressSnapshot { public AetheriaRuntimeBehaviorProgressSnapshot(string ownerKind, int ownerIndex, int behaviorIndex, string behaviorKind, double progress) @@ -1031,13 +1076,14 @@ namespace GameCult.Aetheria.State.Verse Progress = progress; } - public string OwnerKind { get; } - public int OwnerIndex { get; } - public int BehaviorIndex { get; } - public string BehaviorKind { get; } - public double Progress { get; } + public string OwnerKind { get; set; } + public int OwnerIndex { get; set; } + public int BehaviorIndex { get; set; } + public string BehaviorKind { get; set; } + public double Progress { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeWeaponStateSnapshot { public AetheriaRuntimeWeaponStateSnapshot( @@ -1082,27 +1128,28 @@ namespace GameCult.Aetheria.State.Verse LockTargetEntityKey = lockTargetEntityKey; } - public string OwnerKind { get; } - public int OwnerIndex { get; } - public int BehaviorIndex { get; } - public string BehaviorKind { get; } - public bool Firing { get; } - public int Ammo { get; } - public int BurstRemaining { get; } - public double BurstTimer { get; } - public double BurstInterval { get; } - public double CooldownProgress { get; } - public bool CoolingDown { get; } - public bool Charging { get; } - public bool Charged { get; } - public double Charge { get; } - public bool Reloading { get; } - public double ReloadProgress { get; } - public double AmmoIntervalProgress { get; } - public double LockProgress { get; } - public string LockTargetEntityKey { get; } + public string OwnerKind { get; set; } + public int OwnerIndex { get; set; } + public int BehaviorIndex { get; set; } + public string BehaviorKind { get; set; } + public bool Firing { get; set; } + public int Ammo { get; set; } + public int BurstRemaining { get; set; } + public double BurstTimer { get; set; } + public double BurstInterval { get; set; } + public double CooldownProgress { get; set; } + public bool CoolingDown { get; set; } + public bool Charging { get; set; } + public bool Charged { get; set; } + public double Charge { get; set; } + public bool Reloading { get; set; } + public double ReloadProgress { get; set; } + public double AmmoIntervalProgress { get; set; } + public double LockProgress { get; set; } + public string LockTargetEntityKey { get; set; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeBehaviorStateSnapshot { public AetheriaRuntimeBehaviorStateSnapshot( @@ -1219,60 +1266,60 @@ namespace GameCult.Aetheria.State.Verse TurretControllerPredictShots = turretControllerPredictShots; } - public string OwnerKind { get; } - public int OwnerIndex { get; } - public int BehaviorIndex { get; } - public string BehaviorKind { get; } - public bool Pinging { get; } - public double PingCooldown { get; } - public double PingLerp { get; } - public double PingRadius { get; } - public int PingedEntityCount { get; } - public double RadiatorTemperature { get; } - public double Emissivity { get; } - public double PumpedHeat { get; } - public double WasteHeat { get; } - public double EnergyUsage { get; } - public double ReactorDraw { get; } - public double ReactorLoadRatio { get; } - public double CapacitorCharge { get; } - public double CapacitorCapacity { get; } - public double CapacitorEfficiency { get; } - public double AetherDriveAxisX { get; } - public double AetherDriveAxisY { get; } - public double AetherDriveAxisZ { get; } - public double AetherDriveThrustX { get; } - public double AetherDriveThrustY { get; } - public double AetherDriveThrustZ { get; } - public double AetherDriveRpmX { get; } - public double AetherDriveRpmY { get; } - public double AetherDriveRpmZ { get; } - public double AetherDriveMaximumRpm { get; } - public double AetherDriveThrustDirectionX { get; } - public double AetherDriveThrustDirectionY { get; } - public string ResourceScannerTargetBodyKey { get; } - public int ResourceScannerAsteroidIndex { get; } - public double ResourceScannerScanTime { get; } - public double ResourceScannerRange { get; } - public double ResourceScannerMinimumDensity { get; } - public double ResourceScannerScanDuration { get; } - public string MiningToolAsteroidBeltKey { get; } - public int MiningToolAsteroidIndex { get; } - public double MiningToolRange { get; } - public double ThrusterAxis { get; } - public double ThrusterThrust { get; } - public double ThrusterTorque { get; } - public double ShieldEfficiency { get; } - public double ShieldEnergyUsage { get; } - public double VelocityLimit { get; } - public double ThermotoggleTargetTemperature { get; } - public bool SwitchActivated { get; } - public bool TriggerPulled { get; } - public bool StatModifierApplied { get; } - public bool StatModifierExecuted { get; } - public int StatModifierTargetStatCount { get; } - public int TurretControllerWeaponCount { get; } - public double TurretControllerShotSpeed { get; } - public bool TurretControllerPredictShots { get; } + public string OwnerKind { get; set; } + public int OwnerIndex { get; set; } + public int BehaviorIndex { get; set; } + public string BehaviorKind { get; set; } + public bool Pinging { get; set; } + public double PingCooldown { get; set; } + public double PingLerp { get; set; } + public double PingRadius { get; set; } + public int PingedEntityCount { get; set; } + public double RadiatorTemperature { get; set; } + public double Emissivity { get; set; } + public double PumpedHeat { get; set; } + public double WasteHeat { get; set; } + public double EnergyUsage { get; set; } + public double ReactorDraw { get; set; } + public double ReactorLoadRatio { get; set; } + public double CapacitorCharge { get; set; } + public double CapacitorCapacity { get; set; } + public double CapacitorEfficiency { get; set; } + public double AetherDriveAxisX { get; set; } + public double AetherDriveAxisY { get; set; } + public double AetherDriveAxisZ { get; set; } + public double AetherDriveThrustX { get; set; } + public double AetherDriveThrustY { get; set; } + public double AetherDriveThrustZ { get; set; } + public double AetherDriveRpmX { get; set; } + public double AetherDriveRpmY { get; set; } + public double AetherDriveRpmZ { get; set; } + public double AetherDriveMaximumRpm { get; set; } + public double AetherDriveThrustDirectionX { get; set; } + public double AetherDriveThrustDirectionY { get; set; } + public string ResourceScannerTargetBodyKey { get; set; } + public int ResourceScannerAsteroidIndex { get; set; } + public double ResourceScannerScanTime { get; set; } + public double ResourceScannerRange { get; set; } + public double ResourceScannerMinimumDensity { get; set; } + public double ResourceScannerScanDuration { get; set; } + public string MiningToolAsteroidBeltKey { get; set; } + public int MiningToolAsteroidIndex { get; set; } + public double MiningToolRange { get; set; } + public double ThrusterAxis { get; set; } + public double ThrusterThrust { get; set; } + public double ThrusterTorque { get; set; } + public double ShieldEfficiency { get; set; } + public double ShieldEnergyUsage { get; set; } + public double VelocityLimit { get; set; } + public double ThermotoggleTargetTemperature { get; set; } + public bool SwitchActivated { get; set; } + public bool TriggerPulled { get; set; } + public bool StatModifierApplied { get; set; } + public bool StatModifierExecuted { get; set; } + public int StatModifierTargetStatCount { get; set; } + public int TurretControllerWeaponCount { get; set; } + public double TurretControllerShotSpeed { get; set; } + public bool TurretControllerPredictShots { get; set; } } } diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeDaemonTradeItemQueries.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeDaemonTradeItemQueries.cs index 566d11cf1..24b2ffb71 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeDaemonTradeItemQueries.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeDaemonTradeItemQueries.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; using System.Globalization; +using MessagePack; #nullable enable namespace GameCult.Aetheria.State.Verse { + [MessagePackObject(true)] public readonly struct AetheriaRuntimeExponentialLerp { public AetheriaRuntimeExponentialLerp(double exponent, double minimum, double maximum) @@ -26,6 +28,7 @@ namespace GameCult.Aetheria.State.Verse } } + [MessagePackObject(true)] public readonly struct AetheriaRuntimeItemRarityTier { public AetheriaRuntimeItemRarityTier(string name, double quality, double red, double green, double blue) @@ -44,6 +47,7 @@ namespace GameCult.Aetheria.State.Verse public double Blue { get; } } + [MessagePackObject(true)] public sealed class AetheriaRuntimeTradeValueSettings { public static AetheriaRuntimeTradeValueSettings Default { get; } = new AetheriaRuntimeTradeValueSettings( @@ -65,8 +69,9 @@ namespace GameCult.Aetheria.State.Verse Tiers = tiers ?? Array.Empty(); } - public AetheriaRuntimeExponentialLerp QualityPriceModifier { get; } - public IReadOnlyList Tiers { get; } + public AetheriaRuntimeExponentialLerp QualityPriceModifier { get; set; } + public IReadOnlyList Tiers { get; set; } = + Array.Empty(); } public readonly struct AetheriaRuntimeTradeItemValue diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeMainMenuSurfaceBuilder.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeMainMenuSurfaceBuilder.cs index c798f2c80..d0bf0c34b 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeMainMenuSurfaceBuilder.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeMainMenuSurfaceBuilder.cs @@ -151,6 +151,15 @@ namespace GameCult.Aetheria.State.Verse string updatedAtUtc, long version) { + var verseLabel = VerseLabel(verseTitle, verseId); + var targetLine = TargetLine(targetLabel, targetKind, targetSource); + var daemonLine = hasAuthoritativeDaemonFrame + ? $"Run {daemonRunId} / frame {daemonFrameId}" + : "No daemon frame"; + var transportLine = string.IsNullOrWhiteSpace(verseCultMeshAddress) + ? verseVisibility + : $"{verseVisibility} / {verseCultMeshAddress}"; + var builder = MainMenuSurface( AetheriaRuntimeMainMenuCommands.RootSurfaceId, "Aetheria Terminus", @@ -171,11 +180,39 @@ namespace GameCult.Aetheria.State.Verse actions.Button("New Game", Operation(AetheriaRuntimeMainMenuCommands.NewGame, "New Game")); actions.Button("Settings", Operation(AetheriaRuntimeMainMenuCommands.ShowSettings, "Settings")); actions.Button("Quit", Operation(AetheriaRuntimeMainMenuCommands.Quit, "Quit")); - }); + }) + .Form( + $"{AetheriaRuntimeMainMenuCommands.RootSurfaceId}.verse", + form => form + .Metric("Verse", verseLabel) + .Metric("Target", targetLine) + .Metric("Daemon", daemonLine) + .Metric("Transport", transportLine)); return AetheriaRuntimeSurfaceDocuments.FromPortableSurface(builder.Build()); } + private static string VerseLabel(string verseTitle, string verseId) + { + if (string.IsNullOrWhiteSpace(verseTitle)) + return string.IsNullOrWhiteSpace(verseId) ? "Unknown Verse" : verseId; + + if (string.IsNullOrWhiteSpace(verseId) || string.Equals(verseTitle, verseId, StringComparison.Ordinal)) + return verseTitle; + + return $"{verseTitle} / {verseId}"; + } + + private static string TargetLine(string targetLabel, string targetKind, string targetSource) + { + var label = string.IsNullOrWhiteSpace(targetLabel) ? "Unknown target" : targetLabel; + var kind = string.IsNullOrWhiteSpace(targetKind) ? "unknown" : targetKind; + if (string.IsNullOrWhiteSpace(targetSource)) + return $"{label} ({kind})"; + + return $"{label} ({kind}) / {targetSource}"; + } + public static AetheriaRuntimeSurfaceDocument BuildSettings( string updatedAtUtc, long version = 1) diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimePlayerSettingsSurfaceBuilder.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimePlayerSettingsSurfaceBuilder.cs index c52815919..f732facde 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimePlayerSettingsSurfaceBuilder.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimePlayerSettingsSurfaceBuilder.cs @@ -5,137 +5,6 @@ using GameCult.Mesh; namespace GameCult.Aetheria.State.Verse { - public static class AetheriaRuntimeSurfaceStateRefs - { - public const string Source = "stateRef"; - public const string Value = "valueRef"; - public const string Label = "labelRef"; - public const string Format = "stateFormat"; - - public static (string Key, string Value) SourceRef(string reference) - { - return (Source, reference ?? ""); - } - - public static (string Key, string Value) ValueRef(string reference) - { - return (Value, reference ?? ""); - } - - public static (string Key, string Value) LabelRef(string reference) - { - return (Label, reference ?? ""); - } - - public static (string Key, string Value) FormatRef(string format) - { - return (Format, format ?? ""); - } - } - - public static class AetheriaRuntimeSurfaceStateBindings - { - public const string PropPrefix = "cultmesh.statePointer."; - public const string PointerIdSuffix = ".pointerId"; - public const string SourceIdSuffix = ".sourceId"; - public const string SchemaIdSuffix = ".schemaId"; - public const string RouteKindSuffix = ".routeKind"; - public const string RouteDescriptionSuffix = ".routeDescription"; - - public static CultMeshStateBindingDescriptor ForDaemonStateRef( - string targetProp, - string stateRef, - string schemaId = AetheriaRuntimeDaemonSchemas.Frame) - { - return new CultMeshStateBindingDescriptor( - targetProp, - ToPointerId(stateRef), - stateRef, - schemaId, - new CultMeshRouteHint( - CultMeshLocalityKind.SharedMemory, - "daemon-published CultCache state")); - } - - public static IReadOnlyList FromProps( - IReadOnlyDictionary props) - { - if (props == null || props.Count == 0) - return Array.Empty(); - - var bindings = new List(); - AddPropBinding(bindings, "value", Get(props, AetheriaRuntimeSurfaceStateRefs.Source)); - foreach (var prop in props) - { - if (string.IsNullOrWhiteSpace(prop.Value) || - string.Equals(prop.Key, AetheriaRuntimeSurfaceStateRefs.Source, StringComparison.Ordinal) || - !prop.Key.EndsWith("Ref", StringComparison.Ordinal)) - { - continue; - } - - AddPropBinding(bindings, prop.Key.Substring(0, prop.Key.Length - "Ref".Length), prop.Value); - } - - return bindings; - } - - public static void AddPointerProps( - IDictionary props, - IReadOnlyList bindings) - { - if (props == null || bindings == null) - return; - - foreach (var binding in bindings) - { - if (binding == null || string.IsNullOrWhiteSpace(binding.PointerId)) - continue; - - var record = CultMesh.StateBindingRecord(binding); - var prefix = PropPrefix + record.TargetProp; - props[prefix + PointerIdSuffix] = record.PointerId; - props[prefix + SourceIdSuffix] = record.SourceId; - props[prefix + SchemaIdSuffix] = record.SchemaId; - props[prefix + RouteKindSuffix] = record.RouteKind; - props[prefix + RouteDescriptionSuffix] = record.RouteDescription; - } - } - - private static void AddPropBinding( - List bindings, - string targetProp, - string stateRef) - { - if (string.IsNullOrWhiteSpace(stateRef)) - return; - - var schemaId = stateRef.StartsWith(AetheriaRuntimeDaemonItemStatQueries.StateRefPrefix + "/", StringComparison.Ordinal) - ? AetheriaRuntimeDaemonSchemas.CurrentEntity - : AetheriaRuntimeDaemonSchemas.Frame; - bindings.Add(ForDaemonStateRef(targetProp, stateRef, schemaId)); - } - - private static string Get(IReadOnlyDictionary props, string key) - { - return props.TryGetValue(key, out var value) ? value : ""; - } - - private static string ToPointerId(string stateRef) - { - if (string.IsNullOrWhiteSpace(stateRef)) - return ""; - - var chars = stateRef - .Select(character => char.IsLetterOrDigit(character) ? char.ToLowerInvariant(character) : '.') - .ToArray(); - var pointerId = new string(chars).Trim('.'); - while (pointerId.Contains("..", StringComparison.Ordinal)) - pointerId = pointerId.Replace("..", ".", StringComparison.Ordinal); - return string.IsNullOrWhiteSpace(pointerId) ? "aetheria.state.unknown" : pointerId; - } - } - public static class AetheriaRuntimePlayerSettingsSurfaceBuilder { public static AetheriaRuntimeSurfaceDocument Build( diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeSurfaceDocuments.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeSurfaceDocuments.cs index 8b9b5d473..e58fc7876 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeSurfaceDocuments.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeSurfaceDocuments.cs @@ -15,6 +15,137 @@ using EveUiSurfaceTree = GameCult.Eve.Surface.EveSurfaceTree; namespace GameCult.Aetheria.State.Verse { + public static class AetheriaRuntimeSurfaceStateRefs + { + public const string Source = "stateRef"; + public const string Value = "valueRef"; + public const string Label = "labelRef"; + public const string Format = "stateFormat"; + + public static (string Key, string Value) SourceRef(string reference) + { + return (Source, reference ?? ""); + } + + public static (string Key, string Value) ValueRef(string reference) + { + return (Value, reference ?? ""); + } + + public static (string Key, string Value) LabelRef(string reference) + { + return (Label, reference ?? ""); + } + + public static (string Key, string Value) FormatRef(string format) + { + return (Format, format ?? ""); + } + } + + public static class AetheriaRuntimeSurfaceStateBindings + { + public const string PropPrefix = "cultmesh.statePointer."; + public const string PointerIdSuffix = ".pointerId"; + public const string SourceIdSuffix = ".sourceId"; + public const string SchemaIdSuffix = ".schemaId"; + public const string RouteKindSuffix = ".routeKind"; + public const string RouteDescriptionSuffix = ".routeDescription"; + + public static CultMeshStateBindingDescriptor ForDaemonStateRef( + string targetProp, + string stateRef, + string schemaId = AetheriaRuntimeDaemonSchemas.Frame) + { + return new CultMeshStateBindingDescriptor( + targetProp, + ToPointerId(stateRef), + stateRef, + schemaId, + new CultMeshRouteHint( + CultMeshLocalityKind.SharedMemory, + "daemon-published CultCache state")); + } + + public static IReadOnlyList FromProps( + IReadOnlyDictionary props) + { + if (props == null || props.Count == 0) + return Array.Empty(); + + var bindings = new List(); + AddPropBinding(bindings, "value", Get(props, AetheriaRuntimeSurfaceStateRefs.Source)); + foreach (var prop in props) + { + if (string.IsNullOrWhiteSpace(prop.Value) || + string.Equals(prop.Key, AetheriaRuntimeSurfaceStateRefs.Source, StringComparison.Ordinal) || + !prop.Key.EndsWith("Ref", StringComparison.Ordinal)) + { + continue; + } + + AddPropBinding(bindings, prop.Key.Substring(0, prop.Key.Length - "Ref".Length), prop.Value); + } + + return bindings; + } + + public static void AddPointerProps( + IDictionary props, + IReadOnlyList bindings) + { + if (props == null || bindings == null) + return; + + foreach (var binding in bindings) + { + if (binding == null || string.IsNullOrWhiteSpace(binding.PointerId)) + continue; + + var record = CultMesh.StateBindingRecord(binding); + var prefix = PropPrefix + record.TargetProp; + props[prefix + PointerIdSuffix] = record.PointerId; + props[prefix + SourceIdSuffix] = record.SourceId; + props[prefix + SchemaIdSuffix] = record.SchemaId; + props[prefix + RouteKindSuffix] = record.RouteKind; + props[prefix + RouteDescriptionSuffix] = record.RouteDescription; + } + } + + private static void AddPropBinding( + List bindings, + string targetProp, + string stateRef) + { + if (string.IsNullOrWhiteSpace(stateRef)) + return; + + var schemaId = stateRef.StartsWith(AetheriaRuntimeDaemonItemStatQueries.StateRefPrefix + "/", StringComparison.Ordinal) + ? AetheriaRuntimeDaemonSchemas.CurrentEntity + : AetheriaRuntimeDaemonSchemas.Frame; + bindings.Add(ForDaemonStateRef(targetProp, stateRef, schemaId)); + } + + private static string Get(IReadOnlyDictionary props, string key) + { + return props.TryGetValue(key, out var value) ? value : ""; + } + + private static string ToPointerId(string stateRef) + { + if (string.IsNullOrWhiteSpace(stateRef)) + return ""; + + var chars = stateRef + .Select(character => char.IsLetterOrDigit(character) ? char.ToLowerInvariant(character) : '.') + .ToArray(); + var pointerId = new string(chars).Trim('.'); + while (pointerId.Contains("..", StringComparison.Ordinal)) + pointerId = pointerId.Replace("..", ".", StringComparison.Ordinal); + return string.IsNullOrWhiteSpace(pointerId) ? "aetheria.state.unknown" : pointerId; + } + } + [CultDocument("gamecult.aetheria.runtime_surface", "gamecult.aetheria.runtime_surface.v1")] [MessagePackObject] public sealed class AetheriaRuntimeSurfaceDocument