refactor(modes): share pilot surface across game modes
This commit is contained in:
parent
a3970efd6e
commit
97f86d5365
9 changed files with 16 additions and 33 deletions
|
|
@ -537,7 +537,7 @@ internal sealed class AuthoritySmokeChecks
|
|||
Require(summary.WaveForecast.Length == 1 && summary.WaveForecast[0].DisplayName == "Bomber Line", "starbridge wave forecast should start at current wave");
|
||||
Require(summary.RuntimeRoles.Any(role => role.RuntimeId == "commander-client" && role.Role == "commander"), "starbridge runtime roles should project scenario roles");
|
||||
|
||||
var gameSurface = AetheriaRuntimeDaemonGameSurfaceBuilder.Build(
|
||||
var gameSurface = AetheriaRuntimeDaemonGameSurfaceBuilder.BuildCommander(
|
||||
frame,
|
||||
new AetheriaRuntimeDaemonHealthDocument
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1343,7 +1343,6 @@ static async Task PublishDaemonApiDocumentsAsync(
|
|||
result.Frame,
|
||||
result.Health ?? new AetheriaRuntimeDaemonHealthDocument(),
|
||||
result.CommandBoundary ?? AetheriaRuntimeDaemonCommandBoundaryDocument.Create(options.DaemonId),
|
||||
result.StarbridgeSessionSummary,
|
||||
activeMainMenuSurfaceId);
|
||||
await node.MutableDocument<EveSurfaceDocument>(AetheriaRuntimeVerseRecordKeys.DaemonGameSurface)
|
||||
.ReplaceAsync(AetheriaRuntimeSurfaceDocuments.ToPortableSurface(gameSurface))
|
||||
|
|
|
|||
|
|
@ -9,23 +9,20 @@ namespace GameCult.Aetheria.State.Verse
|
|||
{
|
||||
public static class AetheriaRuntimeDaemonGameSurfaceBuilder
|
||||
{
|
||||
public const string PilotSurfaceId = "aetheria.starbridge.pilot";
|
||||
public const string PilotSurfaceId = "aetheria.pilot";
|
||||
public const string CommanderSurfaceId = "aetheria.starbridge.commander";
|
||||
public const string SurfaceId = PilotSurfaceId;
|
||||
public const string TuiSurfaceId = "aetheria.starbridge.pilot.tui";
|
||||
public const string TuiSurfaceId = "aetheria.pilot.tui";
|
||||
|
||||
public static AetheriaRuntimeSurfaceDocument Build(
|
||||
AetheriaRuntimeDaemonFrameDocument frame,
|
||||
AetheriaRuntimeDaemonHealthDocument health,
|
||||
AetheriaRuntimeDaemonCommandBoundaryDocument commandBoundary,
|
||||
AetheriaRuntimeStarbridgeSessionSummaryDocument? starbridge = null,
|
||||
string activeMainMenuSurfaceId = AetheriaRuntimeMainMenuCommands.RootSurfaceId)
|
||||
{
|
||||
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 entity = FindCurrentEntity(run, zone);
|
||||
|
|
@ -49,22 +46,6 @@ namespace GameCult.Aetheria.State.Verse
|
|||
Metric("aetheria.daemon.game.frame.observed_commands", "Observed Commands", health.ObservedCommandCount.ToString(CultureInfo.InvariantCulture), AetheriaRuntimeDaemonStateRefs.FrameObservedCommands),
|
||||
Metric("aetheria.daemon.game.frame.applied", "Applied", health.AppliedCommandCount.ToString(CultureInfo.InvariantCulture), AetheriaRuntimeDaemonStateRefs.FrameAppliedCommands),
|
||||
Metric("aetheria.daemon.game.frame.rejected", "Rejected", health.RejectedCommandCount.ToString(CultureInfo.InvariantCulture), AetheriaRuntimeDaemonStateRefs.FrameRejectedCommands)),
|
||||
Node(
|
||||
"aetheria.daemon.game.starbridge",
|
||||
"card",
|
||||
new[] { ("title", "Starbridge Session") },
|
||||
Metric("aetheria.daemon.game.starbridge.scenario", "Scenario", starbridge.ScenarioName),
|
||||
Metric("aetheria.daemon.game.starbridge.session", "Session", starbridge.SessionId),
|
||||
Metric("aetheria.daemon.game.starbridge.phase", "Phase", starbridge.Phase),
|
||||
Metric("aetheria.daemon.game.starbridge.wave", "Wave", starbridge.CurrentWaveIndex.ToString(CultureInfo.InvariantCulture)),
|
||||
Metric("aetheria.daemon.game.starbridge.zone", "Zone", starbridge.ZoneName),
|
||||
Metric("aetheria.daemon.game.starbridge.base", "Base", starbridge.BaseStatus?.DisplayName ?? ""),
|
||||
Metric("aetheria.daemon.game.starbridge.base_hull", "Base Hull", FormatNumber(starbridge.BaseStatus?.Hull ?? 0)),
|
||||
Metric("aetheria.daemon.game.starbridge.base_shield", "Base Shield", FormatNumber(starbridge.BaseStatus?.Shield ?? 0)),
|
||||
Metric("aetheria.daemon.game.starbridge.base_heat", "Base Heat", FormatNumber(starbridge.BaseStatus?.Heat ?? 0))),
|
||||
BuildStarbridgeStationStockCard(starbridge),
|
||||
BuildStarbridgeWaveForecastCard(starbridge),
|
||||
BuildStarbridgeRuntimeRolesCard(starbridge),
|
||||
Node(
|
||||
"aetheria.daemon.game.player",
|
||||
"card",
|
||||
|
|
|
|||
|
|
@ -225,8 +225,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
var gameSurface = AetheriaRuntimeDaemonGameSurfaceBuilder.Build(
|
||||
frame,
|
||||
health,
|
||||
commandBoundary,
|
||||
starbridgeSummary);
|
||||
commandBoundary);
|
||||
var designerSurfaces = new[]
|
||||
{
|
||||
AetheriaRuntimeStatRecipeSurfaceBuilder.BuildFromCatalog(catalog),
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ namespace GameCult.Aetheria.State.Verse
|
|||
AetheriaRuntimePlayerSettingsCommands.IncrementSignificantDigits,
|
||||
AetheriaRuntimePlayerSettingsCommands.CycleNebulaQuality,
|
||||
AetheriaRuntimePlayerSettingsCommands.ToggleShowAsteroidsInMinimap),
|
||||
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.PilotSurfaceId, "Aetheria Pilot", AetheriaRuntimeVerseRecordKeys.DaemonGameSurface.ToString(), "pilot", "Embodied pilot projection shared by Terminus and Starbridge.", 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")),
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@
|
|||
"purpose": "Proves Aetheria interactive world clients consume provider advertisements, lower provider-owned game surfaces, issue command intents through the daemon boundary, and receive provider-owned receipts.",
|
||||
"requires": {
|
||||
"fixtures": ["aetheria-world"],
|
||||
"surfaces": ["aetheria.starbridge.pilot", "aetheria.starbridge.commander", "aetheria.daemon.editor"],
|
||||
"surfaces": ["aetheria.pilot", "aetheria.starbridge.commander", "aetheria.daemon.editor"],
|
||||
"worldSurfaces": [
|
||||
{
|
||||
"surfaceId": "aetheria.starbridge.pilot",
|
||||
"surfaceId": "aetheria.pilot",
|
||||
"surfaceKind": "interactive-world",
|
||||
"projectionKind": "provider-authored-world-surface",
|
||||
"commandBoundary": "aetheria.daemon.commands",
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
"version": 1,
|
||||
"updatedAtUtc": "2026-07-08T00:00:00Z",
|
||||
"surface": {
|
||||
"id": "aetheria.starbridge.pilot",
|
||||
"id": "aetheria.pilot",
|
||||
"root": {
|
||||
"id": "aetheria.daemon.game.root",
|
||||
"kind": "surface",
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@
|
|||
},
|
||||
{
|
||||
"schema": "gamecult.eve.surface.v1",
|
||||
"surfaceId": "aetheria.starbridge.pilot",
|
||||
"surfaceId": "aetheria.pilot",
|
||||
"key": "AetheriaRuntimeVerseRecordKeys.DaemonGameSurface",
|
||||
"transport": "cultmesh-record",
|
||||
"status": "available",
|
||||
|
|
@ -115,7 +115,7 @@
|
|||
"loweringTargets": ["web-reference", "unity-uitoolkit", "unity-scene", "electron-shell", "tui"],
|
||||
"ownership": "provider-owns-world-state-assets-command-acceptance-and-receipts"
|
||||
},
|
||||
"summary": "Embodied Starbridge pilot surface lowered by generic Eve runtimes."
|
||||
"summary": "Embodied pilot surface shared by Terminus and Starbridge and lowered by generic Eve runtimes."
|
||||
},
|
||||
{
|
||||
"schema": "gamecult.eve.surface.v1",
|
||||
|
|
@ -143,7 +143,7 @@
|
|||
},
|
||||
{
|
||||
"schema": "gamecult.eve.surface.v1",
|
||||
"surfaceId": "aetheria.starbridge.pilot.tui",
|
||||
"surfaceId": "aetheria.pilot.tui",
|
||||
"key": "AetheriaRuntimeVerseRecordKeys.DaemonGameTuiSurface",
|
||||
"transport": "cultmesh-record",
|
||||
"status": "available",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const advertisement = read(pack.advertisementPath);
|
|||
assert.equal(advertisement.providerId, pack.providerId);
|
||||
const starbridgeSurfaces = advertisement.surfaces.filter((surface) =>
|
||||
surface.surfaceId === "aetheria.starbridge.commander" ||
|
||||
surface.surfaceId === "aetheria.starbridge.pilot");
|
||||
surface.surfaceId === "aetheria.pilot");
|
||||
assert.equal(starbridgeSurfaces.length, 2);
|
||||
assert.deepEqual(new Set(starbridgeSurfaces.map((surface) => surface.audience)), new Set(["commander", "pilot"]));
|
||||
for (const surface of starbridgeSurfaces) {
|
||||
|
|
@ -21,6 +21,10 @@ for (const surface of starbridgeSurfaces) {
|
|||
assert.ok(surface.worldInteraction?.loweringTargets.includes("electron-shell"));
|
||||
assert.ok(surface.worldInteraction?.loweringTargets.includes("unity-scene"));
|
||||
}
|
||||
const pilotSurface = advertisement.surfaces.find((surface) => surface.surfaceId === "aetheria.pilot");
|
||||
assert.ok(pilotSurface);
|
||||
assert.match(pilotSurface.summary, /Terminus and Starbridge/);
|
||||
assert.doesNotMatch(pilotSurface.surfaceId, /starbridge|terminus/);
|
||||
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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue