feat(starbridge): publish commander and pilot surfaces

This commit is contained in:
Meta Vens 2026-07-11 00:51:50 +01:00
commit fdcff0f2d6
7 changed files with 142 additions and 17 deletions

View file

@ -75,7 +75,7 @@ app.whenReady().then(async () => {
},
renderer: rendererIndex,
runtimeId: "eve-electron-aetheria",
surfaceId: process.env.EVE_SURFACE_ID || "aetheria.game",
surfaceId: process.env.EVE_SURFACE_ID || "aetheria.starbridge.commander",
window: {
show: !electronSmoke,
backgroundColor: "#0b1016",
@ -87,10 +87,10 @@ app.whenReady().then(async () => {
if (electronSmoke) {
await withTimeout(mainWindow.webContents.executeJavaScript("window.eveProvider.providerAdvertisement()"), 10000, "provider advertisement smoke");
writeElectronSmokeResult({ ok: false, stage: "provider-advertisement-readable" });
await withTimeout(mainWindow.webContents.executeJavaScript("window.eveProvider.surface({ surfaceId: 'aetheria.game' })"), 10000, "surface smoke");
await withTimeout(mainWindow.webContents.executeJavaScript("window.eveProvider.surface({ surfaceId: 'aetheria.starbridge.commander' })"), 10000, "surface smoke");
writeElectronSmokeResult({ ok: false, stage: "provider-surface-readable" });
await withTimeout(mainWindow.webContents.executeJavaScript(`window.eveProvider.submitCommand({
providerId: 'aetheria.daemon', surfaceId: 'aetheria.game', command: 'aetheria.daemon.commands.SensorPing',
providerId: 'aetheria.daemon', surfaceId: 'aetheria.starbridge.commander', command: 'aetheria.daemon.commands.SensorPing',
clientId: 'aetheria-electron-smoke-preflight', payload: {}
})`), 10000, "command receipt smoke");
writeElectronSmokeResult({ ok: false, stage: "provider-command-receipt-readable" });
@ -160,7 +160,7 @@ async function runElectronSmoke(window: BrowserWindow): Promise<Record<string, u
});
const eveReceipt = eveProvider ? await eveProvider.submitCommand({
providerId: "aetheria.daemon",
surfaceId: "aetheria.game",
surfaceId: "aetheria.starbridge.commander",
command: "aetheria.daemon.commands.SensorPing",
clientId: "aetheria-electron-smoke",
payload: {},
@ -214,10 +214,10 @@ function isElectronSmokeReady(result: Record<string, unknown>): boolean {
result.worldSceneReady === true &&
Number(result.worldEntityCount) > 0 &&
Number(result.controlledWorldEntityCount) === 1 &&
eveHostText.includes("Daemon Frame") &&
eveHostText.includes("Typed Command Boundary") &&
arrayValue(providerAdvertisement?.surfaces).some(surface => objectValue(surface)?.surfaceId === "aetheria.game") &&
objectValue(eveSurface?.surface)?.id === "aetheria.game" &&
eveHostText.includes("Station Stock") &&
eveHostText.includes("Wave Forecast") &&
arrayValue(providerAdvertisement?.surfaces).some(surface => objectValue(surface)?.surfaceId === "aetheria.starbridge.commander") &&
objectValue(eveSurface?.surface)?.id === "aetheria.starbridge.commander" &&
stringValue(renderSplatsResolved?.documentId).length > 0 &&
stringValue(gravityResolved?.documentId).length > 0 &&
stringValue(objectsResolved?.documentId).length > 0 &&

View file

@ -1348,6 +1348,14 @@ static async Task PublishDaemonApiDocumentsAsync(
await node.MutableDocument<EveSurfaceDocument>(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface)
.ReplaceAsync(AetheriaRuntimeSurfaceDocuments.ToPortableSurface(gameSurface))
.ConfigureAwait(false);
var commanderSurface = AetheriaRuntimeDaemonGameSurfaceBuilder.BuildCommander(
result.Frame,
result.Health ?? new AetheriaRuntimeDaemonHealthDocument(),
result.CommandBoundary ?? AetheriaRuntimeDaemonCommandBoundaryDocument.Create(options.DaemonId),
result.StarbridgeSessionSummary);
await node.MutableDocument<EveSurfaceDocument>(AetheriaRuntimeVerseRecordKeys.StarbridgeCommanderSurface)
.ReplaceAsync(AetheriaRuntimeSurfaceDocuments.ToPortableSurface(commanderSurface))
.ConfigureAwait(false);
if (result.GameTuiSurface != null)
await node.MutableDocument<EveSurfaceDocument>(AetheriaRuntimeVerseRecordKeys.DaemonGameTuiSurface)
.ReplaceAsync(AetheriaRuntimeSurfaceDocuments.ToPortableSurface(result.GameTuiSurface))
@ -1398,12 +1406,20 @@ static EveProviderAdvertisementDocument BuildCoreProviderAdvertisement(
new[]
{
new EveAdvertisedSurface(
AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId,
AetheriaRuntimeDaemonGameSurfaceBuilder.PilotSurfaceId,
EveSurfaceDocument.SchemaId,
AetheriaRuntimeVerseRecordKeys.DaemonGameSurface.ToString(),
"cultmesh-record",
"active",
"interactive-world",
interaction),
new EveAdvertisedSurface(
AetheriaRuntimeDaemonGameSurfaceBuilder.CommanderSurfaceId,
EveSurfaceDocument.SchemaId,
AetheriaRuntimeVerseRecordKeys.StarbridgeCommanderSurface.ToString(),
"cultmesh-record",
"active",
"interactive-world",
interaction)
},
Array.Empty<EveAdvertisedCommand>());

View file

@ -9,8 +9,10 @@ namespace GameCult.Aetheria.State.Verse
{
public static class AetheriaRuntimeDaemonGameSurfaceBuilder
{
public const string SurfaceId = "aetheria.game";
public const string TuiSurfaceId = "aetheria.game.tui";
public const string PilotSurfaceId = "aetheria.starbridge.pilot";
public const string CommanderSurfaceId = "aetheria.starbridge.commander";
public const string SurfaceId = PilotSurfaceId;
public const string TuiSurfaceId = "aetheria.starbridge.pilot.tui";
public static AetheriaRuntimeSurfaceDocument Build(
AetheriaRuntimeDaemonFrameDocument frame,
@ -126,6 +128,75 @@ namespace GameCult.Aetheria.State.Verse
.ToArray());
}
public static AetheriaRuntimeSurfaceDocument BuildCommander(
AetheriaRuntimeDaemonFrameDocument frame,
AetheriaRuntimeDaemonHealthDocument health,
AetheriaRuntimeDaemonCommandBoundaryDocument commandBoundary,
AetheriaRuntimeStarbridgeSessionSummaryDocument? starbridge = null)
{
frame ??= new AetheriaRuntimeDaemonFrameDocument();
health ??= new AetheriaRuntimeDaemonHealthDocument();
commandBoundary ??= AetheriaRuntimeDaemonCommandBoundaryDocument.Create(frame.DaemonId);
starbridge ??= AetheriaRuntimeStarbridgeDocuments.SessionSummary(frame);
var run = frame.Run ?? new AetheriaRuntimeRunCheckpointCommit();
var zone = FindCurrentZone(run);
var root = SurfaceRoot(
"aetheria.starbridge.commander.root",
StrategicWorldSurface("aetheria.starbridge.commander.world", run, zone),
BuildStarbridgeStationStockCard(starbridge),
BuildStarbridgeWaveForecastCard(starbridge),
BuildStarbridgeRuntimeRolesCard(starbridge));
return new AetheriaRuntimeSurfaceDocument(
"aetheria.daemon",
"game.daemon",
"Starbridge Commander",
frame.FrameId,
frame.PublishedAtUtc,
new AetheriaRuntimeSurfaceTree(
CommanderSurfaceId,
root,
Array.Empty<AetheriaRuntimeSurfaceStyleToken>()),
commandBoundary.Commands
.Where(entry => AetheriaRuntimeDaemonSurfaceCommandCatalog.IsArgumentlessCommand(entry.Kind))
.Select(entry => new AetheriaRuntimeSurfaceCommandTemplate(
AetheriaRuntimeDaemonSurfaceCommandCatalog.CommandName(entry.Kind),
AetheriaRuntimeDaemonSurfaceCommandCatalog.Label(entry.Kind),
"cultmesh"))
.ToArray());
}
private static AetheriaRuntimeSurfaceComponent StrategicWorldSurface(
string id,
AetheriaRuntimeRunCheckpointCommit run,
AetheriaRuntimeZoneSnapshotCommit zone)
{
var props = new Dictionary<string, string>(StringComparer.Ordinal)
{
["label"] = string.IsNullOrWhiteSpace(zone.Name) ? "Starbridge" : zone.Name,
["statePointerId"] = AetheriaRuntimeVerseRecordKeys.DaemonFrameLatest.ToString(),
["assetManifest"] = AetheriaRuntimeVerseRecordKeys.EveAssetCatalog.ToString(),
["inputProfile"] = "rts.pointer-keyboard.v1",
["cameraRig"] = "rts.top-down.v1",
["zoneIndex"] = zone.ZoneIndex.ToString(CultureInfo.InvariantCulture),
["runId"] = run.RunId ?? ""
};
var entities = (zone.Entities ?? Array.Empty<AetheriaRuntimeEntitySnapshotCommit>())
.Where(entity => entity != null && entity.IsActive)
.Select(entity => PlayableWorldEntity(entity, run, zone, run.CurrentEntityKey))
.ToArray();
return new AetheriaRuntimeSurfaceComponent(
id,
"world.scene2d",
props,
entities,
AetheriaRuntimeSurfaceStateBindings.FromProps(props),
Array.Empty<AetheriaRuntimeEmbeddedDocumentSlot>(),
Layout(("position", "absolute"), ("inset", "0"), ("width", "100%"), ("height", "100%")),
new Dictionary<string, string> { ["background"] = "transparent" });
}
private static AetheriaRuntimeSurfaceComponent BuildStarbridgeStationStockCard(
AetheriaRuntimeStarbridgeSessionSummaryDocument summary)
{

View file

@ -110,7 +110,8 @@ namespace GameCult.Aetheria.State.Verse
AetheriaRuntimePlayerSettingsCommands.IncrementSignificantDigits,
AetheriaRuntimePlayerSettingsCommands.CycleNebulaQuality,
AetheriaRuntimePlayerSettingsCommands.ToggleShowAsteroidsInMinimap),
Surface(AetheriaRuntimeDaemonGameSurfaceBuilder.SurfaceId, "Aetheria Daemon", AetheriaRuntimeVerseRecordKeys.DaemonGameSurface.ToString(), "player", "Authoritative daemon game surface.", providerId: "aetheria.daemon", providerKind: "game.daemon", transport: "cultmesh-record", surfaceKind: "interactive-world", worldInteraction: WorldInteraction("provider-authored-world-surface"), requiresPlugins: FieldPluginRequirements()),
Surface(AetheriaRuntimeDaemonGameSurfaceBuilder.PilotSurfaceId, "Starbridge Pilot", AetheriaRuntimeVerseRecordKeys.DaemonGameSurface.ToString(), "pilot", "Embodied Starbridge pilot projection.", providerId: "aetheria.daemon", providerKind: "game.daemon", transport: "cultmesh-record", surfaceKind: "interactive-world", worldInteraction: WorldInteraction("provider-authored-world-surface"), requiresPlugins: FieldPluginRequirements()),
Surface(AetheriaRuntimeDaemonGameSurfaceBuilder.CommanderSurfaceId, "Starbridge Commander", AetheriaRuntimeVerseRecordKeys.StarbridgeCommanderSurface.ToString(), "commander", "Strategic Starbridge commander projection.", providerId: "aetheria.daemon", providerKind: "game.daemon", transport: "cultmesh-record", surfaceKind: "interactive-world", worldInteraction: WorldInteraction("provider-authored-world-surface"), requiresPlugins: FieldPluginRequirements()),
Surface(AetheriaRuntimeDaemonGameSurfaceBuilder.TuiSurfaceId, "Aetheria Daemon TUI", AetheriaRuntimeVerseRecordKeys.DaemonGameTuiSurface.ToString(), "agent", "Compact daemon game surface for dense inspection.", providerId: "aetheria.daemon", providerKind: "game.daemon", transport: "cultmesh-record", surfaceKind: "interactive-world", worldInteraction: WorldInteraction("provider-authored-world-surface")),
Surface(AetheriaRuntimeDaemonEditorSurfaceBuilder.SurfaceId, "Aetheria Daemon Editor", AetheriaRuntimeVerseRecordKeys.DaemonEditorSurface.ToString(), "operator", "Daemon editor and surface inventory.", providerId: "aetheria.daemon", providerKind: "editor.daemon", transport: "cultmesh-record", surfaceKind: "interactive-world-editor", worldInteraction: WorldInteraction("provider-authored-world-editor-surface")),
Surface(AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId, "Aetheria Daemon Editor TUI", AetheriaRuntimeVerseRecordKeys.DaemonEditorTuiSurface.ToString(), "agent", "Compact daemon editor and surface inventory.", providerId: "aetheria.daemon", providerKind: "editor.daemon", transport: "cultmesh-record", surfaceKind: "interactive-world-editor", worldInteraction: WorldInteraction("provider-authored-world-editor-surface")),

View file

@ -67,6 +67,9 @@ namespace GameCult.Aetheria.State.Verse
public static CultRecordKey DaemonGameSurface { get; } =
new CultRecordKey("eve:surface:aetheria.daemon.game");
public static CultRecordKey StarbridgeCommanderSurface { get; } =
new CultRecordKey("eve:surface:aetheria.starbridge.commander");
public static CultRecordKey DaemonGameTuiSurface { get; } =
new CultRecordKey("eve:surface:aetheria.daemon.game.tui");

View file

@ -95,11 +95,11 @@
},
{
"schema": "gamecult.eve.surface.v1",
"surfaceId": "aetheria.daemon.game",
"surfaceId": "aetheria.starbridge.pilot",
"key": "AetheriaRuntimeVerseRecordKeys.DaemonGameSurface",
"transport": "cultmesh-record",
"status": "available",
"audience": "player",
"audience": "pilot",
"mode": "interactive",
"surfaceKind": "interactive-world",
"interactionModel": "provider-command-receipts",
@ -115,11 +115,35 @@
"loweringTargets": ["web-reference", "unity-uitoolkit", "unity-scene", "electron-shell", "tui"],
"ownership": "provider-owns-world-state-assets-command-acceptance-and-receipts"
},
"summary": "Authoritative daemon game surface consumed by Unity, Electron, and web lowerers."
"summary": "Embodied Starbridge pilot surface lowered by generic Eve runtimes."
},
{
"schema": "gamecult.eve.surface.v1",
"surfaceId": "aetheria.daemon.game.tui",
"surfaceId": "aetheria.starbridge.commander",
"key": "AetheriaRuntimeVerseRecordKeys.StarbridgeCommanderSurface",
"transport": "cultmesh-record",
"status": "available",
"audience": "commander",
"mode": "interactive",
"surfaceKind": "interactive-world",
"interactionModel": "provider-command-receipts",
"worldInteraction": {
"projectionKind": "provider-authored-world-surface",
"stateSchemas": [
"aetheria.world_state.v1",
"aetheria.runtime.daemon.frame.v1",
"aetheria.runtime.daemon.soa_view.v1"
],
"commandBoundary": "aetheria.daemon.commands",
"receiptSchema": "aetheria.eve_command_acceptance_status.v1",
"loweringTargets": ["web-reference", "unity-uitoolkit", "unity-scene", "electron-shell", "tui"],
"ownership": "provider-owns-world-state-assets-command-acceptance-and-receipts"
},
"summary": "Strategic Starbridge surface lowered full-screen by Electron or embedded by Unity."
},
{
"schema": "gamecult.eve.surface.v1",
"surfaceId": "aetheria.starbridge.pilot.tui",
"key": "AetheriaRuntimeVerseRecordKeys.DaemonGameTuiSurface",
"transport": "cultmesh-record",
"status": "available",

View file

@ -10,7 +10,17 @@ assert.equal(pack.ownerRepo, "Aetheria");
const advertisement = read(pack.advertisementPath);
assert.equal(advertisement.providerId, pack.providerId);
assert.ok(advertisement.surfaces.some((surface) => surface.surfaceId === "aetheria.daemon.game" && surface.worldInteraction?.projectionKind === "provider-authored-world-surface"));
const starbridgeSurfaces = advertisement.surfaces.filter((surface) =>
surface.surfaceId === "aetheria.starbridge.commander" ||
surface.surfaceId === "aetheria.starbridge.pilot");
assert.equal(starbridgeSurfaces.length, 2);
assert.deepEqual(new Set(starbridgeSurfaces.map((surface) => surface.audience)), new Set(["commander", "pilot"]));
for (const surface of starbridgeSurfaces) {
assert.equal(surface.worldInteraction?.projectionKind, "provider-authored-world-surface");
assert.equal(surface.worldInteraction?.commandBoundary, "aetheria.daemon.commands");
assert.ok(surface.worldInteraction?.loweringTargets.includes("electron-shell"));
assert.ok(surface.worldInteraction?.loweringTargets.includes("unity-scene"));
}
assert.ok(advertisement.surfaces.some((surface) => surface.surfaceId === "aetheria.daemon.editor" && surface.worldInteraction?.projectionKind === "provider-authored-world-editor-surface"));
for (const fixture of pack.fixtures) {