Mount Eve operations surface at runtime
This commit is contained in:
parent
b130df9557
commit
38ff448d4c
6 changed files with 129 additions and 3 deletions
Binary file not shown.
|
|
@ -9,6 +9,7 @@ var statePath = args.Length > 1
|
|||
|
||||
RequireGameplaySourcePurity(root);
|
||||
RequirePackageSerializerBoundary(root);
|
||||
RequireEveRuntimeBootstrap(root);
|
||||
|
||||
await using var node = await AetheriaStateNode.OpenAsync(statePath, "aetheria-state-verify");
|
||||
|
||||
|
|
@ -447,6 +448,7 @@ 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("Eve runtime bootstrap: operations surface mounts through UI Toolkit presenter");
|
||||
|
||||
static void RequireCount(AetheriaMigrationLedger ledger, string documentType, int actual)
|
||||
{
|
||||
|
|
@ -549,6 +551,49 @@ static void RequirePackageSerializerBoundary(string root)
|
|||
}
|
||||
}
|
||||
|
||||
static void RequireEveRuntimeBootstrap(string root)
|
||||
{
|
||||
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");
|
||||
|
||||
if (!File.Exists(bootstrapPath))
|
||||
{
|
||||
throw new InvalidOperationException("Aetheria Eve runtime bootstrap is missing.");
|
||||
}
|
||||
|
||||
if (!File.Exists(presenterPath))
|
||||
{
|
||||
throw new InvalidOperationException("Aetheria Eve surface presenter is missing.");
|
||||
}
|
||||
|
||||
var bootstrap = File.ReadAllText(bootstrapPath);
|
||||
if (!bootstrap.Contains("RuntimeInitializeOnLoadMethod", StringComparison.Ordinal) ||
|
||||
!bootstrap.Contains("DefaultSurfaceId = \"aetheria.operations\"", StringComparison.Ordinal) ||
|
||||
!bootstrap.Contains("AetheriaEveSurfacePresenter", StringComparison.Ordinal) ||
|
||||
!bootstrap.Contains("UIDocument", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Aetheria Eve runtime bootstrap no longer mounts the operations surface through the UI Toolkit presenter.");
|
||||
}
|
||||
|
||||
var presenter = File.ReadAllText(presenterPath);
|
||||
if (!presenter.Contains("AetheriaRuntimeEveCommandLog.QueueCommand", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Aetheria Eve presenter no longer queues renderer commands through the typed Eve command log.");
|
||||
}
|
||||
}
|
||||
|
||||
static bool ContainsBehaviorValueKind(AetheriaBehaviorValue value, string kind)
|
||||
{
|
||||
return string.Equals(value.Kind, kind, StringComparison.OrdinalIgnoreCase) ||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@ provider-owned acceptance organ for those commands: it validates the provider,
|
|||
surface, and command template before running the narrow refresh handlers for
|
||||
the catalog and operations surfaces. Renderer callbacks do not accept commands
|
||||
or mutate game state locally.
|
||||
`AetheriaEveRuntimeBootstrap` mounts the `aetheria.operations` surface through a
|
||||
runtime-created `UIDocument` after scene load, with environment and command-line
|
||||
switches for diagnostics. UI Toolkit is now a live runtime lowering path, not
|
||||
only a package sample.
|
||||
The old `SavedGame`/`SavedZone` DTOs and `Galaxy` loader constructor have also
|
||||
been deleted; the new document family is live Verse run/zone state, not a
|
||||
bespoke save-file format.
|
||||
|
|
@ -288,7 +292,9 @@ named package/import CultCache transport boundary, not gameplay state authority.
|
|||
The package boundary is also fenced: MessagePack symbols may only appear in the
|
||||
runtime catalog reader, pending CultCache envelope store, and typed runtime/Eve
|
||||
command document files until generated CultCache serializers replace that
|
||||
temporary Unity-side codec.
|
||||
temporary Unity-side codec. The verifier also checks that the Eve runtime
|
||||
bootstrap exists, mounts the operations surface through the UI Toolkit presenter,
|
||||
and keeps renderer commands routed through the typed Eve command log.
|
||||
Use it after import when `GameData/aetheria-world.cc` changes.
|
||||
|
||||
`Aetheria.State.Unity.Smoke` opens the materialized state through the runtime
|
||||
|
|
|
|||
|
|
@ -10,6 +10,15 @@ CultCache state into Unity UI Toolkit.
|
|||
- it queues renderer-emitted commands as typed `.cc.eve.pending` command
|
||||
envelopes for Aetheria's provider-owned command bridge.
|
||||
|
||||
`AetheriaEveRuntimeBootstrap` mounts the first runtime surface after scene load.
|
||||
By default it creates a `UIDocument` host for `aetheria.operations`, so the
|
||||
provider-owned operations surface is present at runtime without a hand-wired
|
||||
scene object. Set `AETHERIA_EVE_SURFACE_ID` to mount a different surface, set
|
||||
`AETHERIA_EVE_STATE_PATH` to point at a non-default `.cc` state file, or disable
|
||||
the automatic mount with `AETHERIA_DISABLE_EVE_RUNTIME_BOOTSTRAP=true` or
|
||||
`--aetheria-disable-eve-runtime-bootstrap`. Batchmode disables the bootstrap so
|
||||
compile and smoke gates do not accidentally create renderer state.
|
||||
|
||||
Commands are surfaced as `gamecult.eve.command.v1` requests. The presenter does
|
||||
not accept or apply them locally; provider acceptance still belongs to the
|
||||
CultMesh command bridge. Renderer-local command effects would be the wrong
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace GameCult.Aetheria.EveRuntime
|
||||
{
|
||||
public static class AetheriaEveRuntimeBootstrap
|
||||
{
|
||||
public const string DefaultSurfaceId = "aetheria.operations";
|
||||
public const string DisableEnvironmentVariable = "AETHERIA_DISABLE_EVE_RUNTIME_BOOTSTRAP";
|
||||
public const string SurfaceEnvironmentVariable = "AETHERIA_EVE_SURFACE_ID";
|
||||
public const string StatePathEnvironmentVariable = "AETHERIA_EVE_STATE_PATH";
|
||||
public const string DisableCommandLineSwitch = "--aetheria-disable-eve-runtime-bootstrap";
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
|
||||
private static void MountDefaultSurface()
|
||||
{
|
||||
if (IsDisabled() || UnityEngine.Object.FindObjectOfType<AetheriaEveSurfacePresenter>() != null)
|
||||
return;
|
||||
|
||||
var host = new GameObject("Aetheria Eve Runtime Surface");
|
||||
UnityEngine.Object.DontDestroyOnLoad(host);
|
||||
|
||||
host.AddComponent<UIDocument>();
|
||||
var presenter = host.AddComponent<AetheriaEveSurfacePresenter>();
|
||||
presenter.SurfaceId = SurfaceId();
|
||||
presenter.StateFilePathOverride = StatePathOverride();
|
||||
}
|
||||
|
||||
private static bool IsDisabled()
|
||||
{
|
||||
if (Application.isBatchMode)
|
||||
return true;
|
||||
|
||||
var environment = Environment.GetEnvironmentVariable(DisableEnvironmentVariable);
|
||||
if (string.Equals(environment, "1", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(environment, "true", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Environment.GetCommandLineArgs()
|
||||
.Any(argument => string.Equals(argument, DisableCommandLineSwitch, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
private static string SurfaceId()
|
||||
{
|
||||
var configured = Environment.GetEnvironmentVariable(SurfaceEnvironmentVariable);
|
||||
return string.IsNullOrWhiteSpace(configured) ? DefaultSurfaceId : configured;
|
||||
}
|
||||
|
||||
private static string StatePathOverride()
|
||||
{
|
||||
return Environment.GetEnvironmentVariable(StatePathEnvironmentVariable) ?? "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -497,6 +497,11 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted.
|
|||
surface lookup, lowering, and command emission into a typed pending queue.
|
||||
Provider command acceptance still belongs to the future CultMesh command
|
||||
bridge.
|
||||
- `AetheriaEveRuntimeBootstrap` mounts the first runtime Eve surface after
|
||||
scene load. The default surface is `aetheria.operations`, hosted in a
|
||||
runtime-created `UIDocument`; environment variables or a command-line switch
|
||||
can redirect/disable the mount for diagnostics. Batchmode disables the
|
||||
bootstrap so verification runs do not create renderer state.
|
||||
- `GameData/aetheria-world.cc` is now materialized from the importer as the
|
||||
project-local typed state file for the checked-in catalog. The importer stores
|
||||
relative provenance in the state document, not machine-local absolute paths.
|
||||
|
|
@ -1341,8 +1346,9 @@ First Aetheria surfaces to publish:
|
|||
serializers directly.
|
||||
- Extend the command bridge beyond refresh commands as gameplay/editor Eve
|
||||
surfaces acquire provider-owned handlers.
|
||||
- Wire the presenter into a Unity scene/prefab for the first runtime surface
|
||||
and replace a concrete uGUI screen.
|
||||
- Done: wire the presenter into runtime through `AetheriaEveRuntimeBootstrap`
|
||||
so the operations surface mounts as a UI Toolkit surface after scene load.
|
||||
- Replace a concrete uGUI screen with an Eve-owned surface.
|
||||
- Move the staged packages into the Eve repo once its worktree is clean, then
|
||||
import them back into Aetheria from Eve instead of carrying a local copy.
|
||||
- Replace the old IMGUI DB inspector first, because it is closest to state
|
||||
|
|
|
|||
Loading…
Reference in a new issue