Move observed sector projection into gameplay boot
This commit is contained in:
parent
d79ba34018
commit
5b7a5b3a8c
5 changed files with 79 additions and 65 deletions
|
|
@ -11145,7 +11145,6 @@ static void RequireMainMenuContinueRunState(string root)
|
|||
".Aetheria()",
|
||||
".LatestSectorMap()",
|
||||
"ContinueGame()",
|
||||
"AetheriaUnityObservedRunProjection.Project(",
|
||||
"SceneManager.LoadScene(\"ARPG\")"
|
||||
};
|
||||
|
||||
|
|
@ -11173,6 +11172,9 @@ static void RequireMainMenuContinueRunState(string root)
|
|||
"GameplayLoopShell.LateTick()",
|
||||
"ApplyLatestZoneRender = () => ObservedFrameApplier.ApplyLatestZoneRender()",
|
||||
"private AetheriaUnityObservedFrameApplier ObservedFrameApplier =>",
|
||||
"private Galaxy ObservedGalaxy { get; set; }",
|
||||
"ObservedGalaxy = boot.ObservedGalaxy",
|
||||
"zoneIndex => AetheriaUnityObservedRunProjection.FindZone(ObservedGalaxy, zoneIndex)",
|
||||
"private AetheriaUnityObservedZoneContextProjector ObservedZoneContextProjector =>",
|
||||
"entity => CurrentEntityBinder.RestoreBinding(entity)",
|
||||
"private AetheriaUnityObservedTargetQuery ObservedTargetQuery =>",
|
||||
|
|
@ -12141,6 +12143,9 @@ static void RequireUnityObserverDoesNotTickLocalSimulation(string root)
|
|||
"ApplyLatestZoneRender = () => ObservedFrameApplier.ApplyLatestZoneRender()",
|
||||
"ResolveDaemonObserver()",
|
||||
"private AetheriaUnityObservedFrameApplier ObservedFrameApplier =>",
|
||||
"private Galaxy ObservedGalaxy { get; set; }",
|
||||
"ObservedGalaxy = boot.ObservedGalaxy",
|
||||
"zoneIndex => AetheriaUnityObservedRunProjection.FindZone(ObservedGalaxy, zoneIndex)",
|
||||
"private AetheriaUnityObservedZoneContextProjector ObservedZoneContextProjector =>",
|
||||
"entity => CurrentEntityBinder.RestoreBinding(entity)",
|
||||
"private AetheriaUnityEntityConstructionBlueprintProjector EntityConstructionBlueprintProjector =>",
|
||||
|
|
@ -13220,10 +13225,7 @@ static void RequireUnityObserverDoesNotTickLocalSimulation(string root)
|
|||
"LatestSectorMap(stateBoot)",
|
||||
".Aetheria()",
|
||||
".LatestSectorMap()",
|
||||
"AetheriaUnityObservedRunProjection.Project(",
|
||||
"sectorMap.FrameId",
|
||||
"sectorMap.IsTutorial",
|
||||
"sectorMap.GenerationSeed",
|
||||
"SceneManager.LoadScene(\"ARPG\")"
|
||||
};
|
||||
|
||||
|
|
@ -13822,6 +13824,7 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
|
|||
var runtimeEveSurfaceAdapterPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaRuntimeEveSurfaceAdapter.cs");
|
||||
var unityPackageProjectPath = Path.Combine(root, "GameCult.Aetheria.State.Unity.csproj");
|
||||
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");
|
||||
var eveSurfacePresenterPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.eve-runtime", "Runtime", "AetheriaEveSurfacePresenter.cs");
|
||||
var eveUnitySurfaceHostPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.eve-runtime", "Runtime", "AetheriaEveUnitySurfaceHost.cs");
|
||||
|
|
@ -13832,6 +13835,7 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
|
|||
runtimeEveSurfaceAdapterPath,
|
||||
unityPackageProjectPath,
|
||||
actionGameManagerPath,
|
||||
gameplayBootShellPath,
|
||||
mainMenuPath,
|
||||
eveSurfacePresenterPath,
|
||||
eveUnitySurfaceHostPath
|
||||
|
|
@ -13853,6 +13857,7 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
|
|||
var runtimeEveSurfaceAdapter = File.ReadAllText(runtimeEveSurfaceAdapterPath);
|
||||
var unityPackageProject = File.ReadAllText(unityPackageProjectPath);
|
||||
var actionGameManager = File.ReadAllText(actionGameManagerPath);
|
||||
var gameplayBootShell = File.ReadAllText(gameplayBootShellPath);
|
||||
var mainMenu = File.ReadAllText(mainMenuPath);
|
||||
var eveSurfacePresenter = File.ReadAllText(eveSurfacePresenterPath);
|
||||
var eveUnitySurfaceHost = File.ReadAllText(eveUnitySurfaceHostPath);
|
||||
|
|
@ -14055,10 +14060,6 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
|
|||
var inputDisplayLayout = File.Exists(inputDisplayLayoutPath)
|
||||
? File.ReadAllText(inputDisplayLayoutPath)
|
||||
: throw new InvalidOperationException("Cannot verify daemon state acquisition; InputDisplayLayout.cs is missing.");
|
||||
var gameplayBootShellPath = Path.Combine(root, "Assets", "Scripts", "Gameplay", "AetheriaUnityGameplayBootShell.cs");
|
||||
var gameplayBootShell = File.Exists(gameplayBootShellPath)
|
||||
? File.ReadAllText(gameplayBootShellPath)
|
||||
: throw new InvalidOperationException("Cannot verify daemon state acquisition; AetheriaUnityGameplayBootShell.cs is missing.");
|
||||
var aetheriaClientPath = Path.Combine(root, "Packages", "org.gamecult.aetheria.state", "Runtime", "AetheriaClient.cs");
|
||||
var aetheriaClient = File.Exists(aetheriaClientPath)
|
||||
? File.ReadAllText(aetheriaClientPath)
|
||||
|
|
@ -14426,10 +14427,8 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
|
|||
|
||||
if (!mainMenu.Contains("AetheriaClient", StringComparison.Ordinal) ||
|
||||
!mainMenu.Contains("LatestSectorMap(AetheriaRuntimeStateBootReport stateBoot)", StringComparison.Ordinal) ||
|
||||
!mainMenu.Contains("LatestRuntimeCatalog(AetheriaRuntimeStateBootReport stateBoot)", StringComparison.Ordinal) ||
|
||||
!mainMenu.Contains(".Aetheria()", StringComparison.Ordinal) ||
|
||||
!mainMenu.Contains(".LatestSectorMap()", StringComparison.Ordinal) ||
|
||||
!mainMenu.Contains(".LatestCatalog()", StringComparison.Ordinal) ||
|
||||
!mainMenu.Contains(".LatestPlayer()", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
|
|
@ -14448,6 +14447,44 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
|
|||
"MainMenu still names runtime catalog access as a raw catalog open instead of a managed latest document read.");
|
||||
}
|
||||
|
||||
if (mainMenu.Contains("LatestRuntimeCatalog(", StringComparison.Ordinal) ||
|
||||
mainMenu.Contains("AetheriaUnityObservedRunProjection.Project(", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"MainMenu still owns gameplay catalog/sector projection instead of leaving observed-scene boot to AetheriaUnityGameplayBootShell.");
|
||||
}
|
||||
|
||||
var requiredGameplayBootSymbols = new[]
|
||||
{
|
||||
".LatestCatalog()",
|
||||
".LatestSectorMap()",
|
||||
"AetheriaUnityObservedRunProjection.Project(",
|
||||
"sectorMap.IsTutorial",
|
||||
"sectorMap.GenerationSeed",
|
||||
"new AetheriaUnityGameplayBootResult(",
|
||||
"ObservedGalaxy"
|
||||
};
|
||||
var missingGameplayBootSymbols = requiredGameplayBootSymbols
|
||||
.Where(symbol => !gameplayBootShell.Contains(symbol, StringComparison.Ordinal))
|
||||
.ToArray();
|
||||
if (missingGameplayBootSymbols.Length > 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"AetheriaUnityGameplayBootShell must own managed catalog/sector-map projection for the observed gameplay scene: " +
|
||||
string.Join(", ", missingGameplayBootSymbols));
|
||||
}
|
||||
|
||||
var observedRunProjectionPath = Path.Combine(root, "Assets", "Scripts", "Gameplay", "AetheriaUnityObservedRunProjection.cs");
|
||||
var observedRunProjection = File.Exists(observedRunProjectionPath)
|
||||
? File.ReadAllText(observedRunProjectionPath)
|
||||
: throw new InvalidOperationException("Cannot verify observed run projection ownership; AetheriaUnityObservedRunProjection.cs is missing.");
|
||||
if (observedRunProjection.Contains("public static Galaxy Galaxy", StringComparison.Ordinal) ||
|
||||
observedRunProjection.Contains("private set;", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"AetheriaUnityObservedRunProjection must be a pure projector; observed galaxy ownership belongs to gameplay boot state.");
|
||||
}
|
||||
|
||||
var forbiddenMainMenuReaderSymbols = new[]
|
||||
{
|
||||
"AetheriaRuntimeStateReader.ReadPlayerSettings",
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public class ActionGameManager : MonoBehaviour
|
|||
_observedZoneContextProjector ??= new AetheriaUnityObservedZoneContextProjector(
|
||||
ItemManager,
|
||||
Settings.PlanetSettings,
|
||||
() => AetheriaUnityObservedRunProjection.Galaxy,
|
||||
() => ObservedGalaxy,
|
||||
Debug.LogWarning,
|
||||
PlayMusic);
|
||||
private AetheriaUnityCurrentEntityBinder CurrentEntityBinder =>
|
||||
|
|
@ -96,7 +96,7 @@ public class ActionGameManager : MonoBehaviour
|
|||
private AetheriaUnityObservedFrameApplier ObservedFrameApplier =>
|
||||
_observedFrameApplier ??= new AetheriaUnityObservedFrameApplier(
|
||||
ResolveDaemonObserver,
|
||||
AetheriaUnityObservedRunProjection.FindZone,
|
||||
zoneIndex => AetheriaUnityObservedRunProjection.FindZone(ObservedGalaxy, zoneIndex),
|
||||
() => Zone,
|
||||
zone => Zone = zone,
|
||||
_observedEntityIndex,
|
||||
|
|
@ -292,6 +292,7 @@ public class ActionGameManager : MonoBehaviour
|
|||
|
||||
private ItemManager ItemManager { get; set; }
|
||||
private AetheriaUnityLoadoutItemProjector _loadoutItemProjector;
|
||||
private Galaxy ObservedGalaxy { get; set; }
|
||||
private Zone Zone { get; set; }
|
||||
|
||||
private readonly AetheriaUnityDragSession _dragSession = new AetheriaUnityDragSession();
|
||||
|
|
@ -319,6 +320,7 @@ public class ActionGameManager : MonoBehaviour
|
|||
var boot = GameplayBootShell.Boot();
|
||||
ItemManager = boot.ItemManager;
|
||||
_loadoutItemProjector = boot.LoadoutItemProjector;
|
||||
ObservedGalaxy = boot.ObservedGalaxy;
|
||||
SceneWiring.ConfigureCurrentEntityPresentation(_currentEntityPresentation, boot.RuntimeCatalog);
|
||||
SceneWiring.ConfigureTargetPresentation(
|
||||
_targetPresentation,
|
||||
|
|
|
|||
|
|
@ -34,13 +34,27 @@ public sealed class AetheriaUnityGameplayBootShell
|
|||
$"Aetheria runtime state file is missing at {stateBoot.StateFilePath}; gameplay requires an authoritative daemon mirror.");
|
||||
}
|
||||
|
||||
var runtimeCatalog = AetheriaUnityRuntimeClientProvider.ResolveClient(stateBoot.StateFilePath, stateBoot.RuntimeId)
|
||||
.Aetheria()
|
||||
.LatestCatalog();
|
||||
var aetheria = AetheriaUnityRuntimeClientProvider.ResolveClient(stateBoot.StateFilePath, stateBoot.RuntimeId)
|
||||
.Aetheria();
|
||||
var runtimeCatalog = aetheria.LatestCatalog();
|
||||
if (runtimeCatalog == null)
|
||||
throw new InvalidOperationException("Aetheria typed runtime catalog is required before gameplay boot.");
|
||||
var sectorMap = aetheria.LatestSectorMap();
|
||||
if (sectorMap == null)
|
||||
throw new InvalidOperationException("Aetheria typed sector map is required before gameplay boot.");
|
||||
|
||||
Log?.Invoke($"Aetheria runtime catalog: {runtimeCatalog.Items.Count} items, {runtimeCatalog.Corporations.Count} corporations, {runtimeCatalog.NameFiles.Count} name files");
|
||||
Log?.Invoke($"Aetheria observed sector-map frame: {sectorMap.FrameId}");
|
||||
|
||||
var backgroundSettings = sectorMap.IsTutorial
|
||||
? Settings.TutorialBackgroundSettings
|
||||
: Settings.SectorBackgroundSettings;
|
||||
backgroundSettings.NoisePosition = sectorMap.GenerationSeed == 0 ? 1 : sectorMap.GenerationSeed;
|
||||
var observedGalaxy = AetheriaUnityObservedRunProjection.Project(
|
||||
sectorMap,
|
||||
backgroundSettings,
|
||||
runtimeCatalog,
|
||||
Log);
|
||||
|
||||
var itemManager = new ItemManager(
|
||||
runtimeCatalog,
|
||||
|
|
@ -60,6 +74,7 @@ public sealed class AetheriaUnityGameplayBootShell
|
|||
|
||||
return new AetheriaUnityGameplayBootResult(
|
||||
runtimeCatalog,
|
||||
observedGalaxy,
|
||||
itemManager,
|
||||
loadoutItemProjector);
|
||||
}
|
||||
|
|
@ -104,15 +119,18 @@ public readonly struct AetheriaUnityGameplayBootResult
|
|||
{
|
||||
public AetheriaUnityGameplayBootResult(
|
||||
AetheriaRuntimeCatalogSnapshot runtimeCatalog,
|
||||
Galaxy observedGalaxy,
|
||||
ItemManager itemManager,
|
||||
AetheriaUnityLoadoutItemProjector loadoutItemProjector)
|
||||
{
|
||||
RuntimeCatalog = runtimeCatalog;
|
||||
ObservedGalaxy = observedGalaxy;
|
||||
ItemManager = itemManager;
|
||||
LoadoutItemProjector = loadoutItemProjector;
|
||||
}
|
||||
|
||||
public AetheriaRuntimeCatalogSnapshot RuntimeCatalog { get; }
|
||||
public Galaxy ObservedGalaxy { get; }
|
||||
public ItemManager ItemManager { get; }
|
||||
public AetheriaUnityLoadoutItemProjector LoadoutItemProjector { get; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,18 +4,16 @@ using GameCult.Aetheria.State.Verse;
|
|||
|
||||
public static class AetheriaUnityObservedRunProjection
|
||||
{
|
||||
public static Galaxy Galaxy { get; private set; }
|
||||
|
||||
public static void Project(
|
||||
public static Galaxy Project(
|
||||
AetheriaRuntimeSectorMapDocument sectorMap,
|
||||
SectorBackgroundSettings backgroundSettings,
|
||||
AetheriaRuntimeCatalogSnapshot runtimeCatalog,
|
||||
Action<string> log)
|
||||
{
|
||||
Galaxy = global::Galaxy.ProjectObservedSectorMap(sectorMap, backgroundSettings, runtimeCatalog, log);
|
||||
return global::Galaxy.ProjectObservedSectorMap(sectorMap, backgroundSettings, runtimeCatalog, log);
|
||||
}
|
||||
|
||||
public static void Project(
|
||||
public static Galaxy Project(
|
||||
AetheriaRuntimeDaemonFrameDocument frame,
|
||||
SectorBackgroundSettings backgroundSettings,
|
||||
AetheriaRuntimeCatalogSnapshot runtimeCatalog,
|
||||
|
|
@ -24,14 +22,14 @@ public static class AetheriaUnityObservedRunProjection
|
|||
if (frame == null || frame.Run == null)
|
||||
throw new ArgumentNullException(nameof(frame));
|
||||
|
||||
Galaxy = global::Galaxy.ProjectObservedDaemonRun(frame.Run, backgroundSettings, runtimeCatalog, log);
|
||||
return global::Galaxy.ProjectObservedDaemonRun(frame.Run, backgroundSettings, runtimeCatalog, log);
|
||||
}
|
||||
|
||||
public static GalaxyZone FindZone(int daemonZoneIndex)
|
||||
public static GalaxyZone FindZone(Galaxy galaxy, int daemonZoneIndex)
|
||||
{
|
||||
return daemonZoneIndex < 0
|
||||
? null
|
||||
: Galaxy?.Zones?.FirstOrDefault(zone => zone != null && zone.ZoneIndex == daemonZoneIndex);
|
||||
: galaxy?.Zones?.FirstOrDefault(zone => zone != null && zone.ZoneIndex == daemonZoneIndex);
|
||||
}
|
||||
|
||||
public static AetheriaRuntimeZoneSnapshotCommit FindZoneSnapshot(AetheriaRuntimeRunCheckpointCommit run)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ public class MainMenu : MonoBehaviour
|
|||
|
||||
private UIDocument _menuSurfaceDocument;
|
||||
private string _clientStatePath;
|
||||
private AetheriaRuntimeCatalogSnapshot _catalog;
|
||||
private Func<bool> _canOpenRuntimeInputScreen;
|
||||
private Action _openRuntimeInputScreen;
|
||||
private readonly AetheriaEveUnitySurfaceChrome _menuSurfaceChrome = new AetheriaEveUnitySurfaceChrome
|
||||
|
|
@ -119,7 +118,7 @@ public class MainMenu : MonoBehaviour
|
|||
return false;
|
||||
}
|
||||
|
||||
var generatorState = "Loading runtime catalog";
|
||||
var generatorState = "Loading daemon sector";
|
||||
Action<string> setState = s => generatorState = s;
|
||||
|
||||
HideMenuSurface();
|
||||
|
|
@ -129,20 +128,6 @@ public class MainMenu : MonoBehaviour
|
|||
Dialog.Show();
|
||||
|
||||
setState($"Observing sector-map frame {sectorMap.FrameId}");
|
||||
var backgroundSettings = sectorMap.IsTutorial ? Settings.TutorialBackgroundSettings : Settings.SectorBackgroundSettings;
|
||||
backgroundSettings.NoisePosition = sectorMap.GenerationSeed == 0 ? 1 : sectorMap.GenerationSeed;
|
||||
var runtimeCatalog = LatestRuntimeCatalog(stateBoot);
|
||||
if (runtimeCatalog == null)
|
||||
{
|
||||
Debug.LogWarning($"Cannot start Aetheria observer scene without a runtime catalog in {stateBoot.StateFilePath}.");
|
||||
return false;
|
||||
}
|
||||
|
||||
AetheriaUnityObservedRunProjection.Project(
|
||||
sectorMap,
|
||||
backgroundSettings,
|
||||
runtimeCatalog,
|
||||
Debug.Log);
|
||||
SceneManager.LoadScene("ARPG");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -210,26 +195,6 @@ public class MainMenu : MonoBehaviour
|
|||
}
|
||||
}
|
||||
|
||||
private AetheriaRuntimeCatalogSnapshot LatestRuntimeCatalog(AetheriaRuntimeStateBootReport stateBoot)
|
||||
{
|
||||
if (!stateBoot.SupportsLocalStateFileRead || !stateBoot.StateFileExists)
|
||||
return null;
|
||||
|
||||
if (_catalog != null)
|
||||
return _catalog;
|
||||
|
||||
try
|
||||
{
|
||||
_catalog = ResolveClient(stateBoot).Aetheria().LatestCatalog();
|
||||
return _catalog;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"Failed to read typed Aetheria runtime catalog for the main menu: {ex}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ContinueGame()
|
||||
{
|
||||
if (!TryStartDaemonObservedGame("Continuing Daemon Run"))
|
||||
|
|
@ -493,17 +458,11 @@ public class MainMenu : MonoBehaviour
|
|||
if (!string.Equals(_clientStatePath, statePath, StringComparison.Ordinal))
|
||||
{
|
||||
_clientStatePath = statePath;
|
||||
ClearClientCaches();
|
||||
}
|
||||
|
||||
return AetheriaUnityRuntimeClientProvider.ResolveClient(stateBoot, "unity-main-menu");
|
||||
}
|
||||
|
||||
private void ClearClientCaches()
|
||||
{
|
||||
_catalog = null;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_menuSurfaceDocument != null)
|
||||
|
|
|
|||
Loading…
Reference in a new issue