From e4266515daa56bcbd726b82faebe64ce6eef077d Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Thu, 18 Jun 2026 05:33:49 +0000 Subject: [PATCH] Land Phase 6C higher-dimensional runtime sessions --- ...rainingHigherDimensionalRuntimeLibrary.cpp | 380 +++++++++++++++++- .../HyperTwistTrainingPanelWidget.cpp | 18 + .../HyperTwistTrainingRuntimeLibrary.cpp | 71 ++++ .../HyperTwistTrainingSessionActor.cpp | 18 + .../HyperTwistTrainingSubsystem.cpp | 13 +- ...tTrainingHigherDimensionalRuntimeLibrary.h | 215 ++++++++++ .../HyperTwistTrainingPanelWidget.h | 10 + .../HyperTwistTrainingRuntimeLibrary.h | 28 ++ .../HyperTwistTrainingSessionActor.h | 10 + ...mensionalPhase6CActivationContractTest.cpp | 130 ++++++ ...NSIVE_RECONSTRUCTION_ROADMAP_2026-06-10.md | 10 + .../HyperTwist/FEATURE_REGISTRY.md | 1 + .../HyperTwist/ROADMAP.md | 13 +- 13 files changed, 909 insertions(+), 8 deletions(-) diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingHigherDimensionalRuntimeLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingHigherDimensionalRuntimeLibrary.cpp index d09132d..aa330df 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingHigherDimensionalRuntimeLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingHigherDimensionalRuntimeLibrary.cpp @@ -73,6 +73,19 @@ namespace HyperTwistTrainingHigherDimensionalRuntimeLibraryInternal return Attribution; } + FHyperTwistTrainingSourceAttribution MakeSessionAttribution( + const FString& SessionSurfaceId, + const FString& Notes + ) + { + FHyperTwistTrainingSourceAttribution Attribution; + Attribution.SourceMode = EHyperTwistTrainingSourceMode::FirstParty; + Attribution.SourceTrackId = TEXT("phase6c/higher-dimensional-runtime-session"); + Attribution.SourceCaseId = SessionSurfaceId; + Attribution.SourceNotes = Notes; + return Attribution; + } + FHyperTwistTrainingImportedRuntimeSelector MakeSelector( const FString& SelectorId, const FString& Label, @@ -101,6 +114,68 @@ namespace HyperTwistTrainingHigherDimensionalRuntimeLibraryInternal return Choice; } + bool ContainsSelectorId( + const TArray& Selectors, + const FString& SelectorId + ) + { + for (const FHyperTwistTrainingImportedRuntimeSelector& Selector : Selectors) + { + if (Selector.SelectorId.Equals(SelectorId, ESearchCase::IgnoreCase)) + { + return true; + } + } + + return false; + } + + bool ContainsSelectorChoiceId( + const TArray& Choices, + const FString& SelectorId + ) + { + for (const FHyperTwistTrainingImportedRuntimeSelectorChoice& Choice : Choices) + { + if (Choice.SelectorId.Equals(SelectorId, ESearchCase::IgnoreCase)) + { + return true; + } + } + + return false; + } + + void AppendUniqueSelectors( + TArray& OutSelectors, + const TArray& InSelectors + ) + { + for (const FHyperTwistTrainingImportedRuntimeSelector& Selector : InSelectors) + { + if (Selector.IsStructurallyValid() + && !ContainsSelectorId(OutSelectors, Selector.SelectorId)) + { + OutSelectors.Add(Selector); + } + } + } + + void AppendUniqueSelectorChoices( + TArray& OutChoices, + const TArray& InChoices + ) + { + for (const FHyperTwistTrainingImportedRuntimeSelectorChoice& Choice : InChoices) + { + if (Choice.IsStructurallyValid() + && !ContainsSelectorChoiceId(OutChoices, Choice.SelectorId)) + { + OutChoices.Add(Choice); + } + } + } + void AppendMagic120CellCapabilityTags( const FHyperTwistTrainingMagic120CellRuntimeProfileContract& RuntimeProfile, const FHyperTwistTrainingMagic120CellPersistenceBoundary& PersistenceBoundary, @@ -814,6 +889,220 @@ namespace HyperTwistTrainingHigherDimensionalRuntimeLibraryInternal ); return ViewContextSurface; } + + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface BuildMagic120CellSessionSurface() + { + FHyperTwistTrainingHigherDimensionalRuntimeLaunchSurface LaunchSurface; + if (!UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryGetRuntimeLaunchSurfaceByActivationProfileId( + UHyperTwistTrainingHigherDimensionalRuntimeLibrary::BuildBundledHigherDimensionalRuntimeLaunchCatalog(), + TEXT("magic120cell-cleanroom-runtime-activation"), + LaunchSurface)) + { + return FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); + } + + FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface ViewContextSurface; + if (!UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryGetRuntimeViewContextSurfaceByActivationProfileId( + UHyperTwistTrainingHigherDimensionalRuntimeLibrary::BuildBundledHigherDimensionalRuntimeViewContextCatalog(), + LaunchSurface.ActivationProfileId, + ViewContextSurface)) + { + return FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); + } + + FHyperTwistTrainingHigherDimensionalRuntimeHostSurface HostSurface; + if (!UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryGetRuntimeHostSurfaceByActivationProfileId( + UHyperTwistTrainingHigherDimensionalRuntimeLibrary::BuildBundledHigherDimensionalRuntimeHostCatalog(), + LaunchSurface.ActivationProfileId, + HostSurface)) + { + return FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); + } + + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface SessionSurface; + SessionSurface.SessionSurfaceId = + TEXT("phase6c/magic120cell/shared-training-session-surface"); + SessionSurface.ActivationProfileId = LaunchSurface.ActivationProfileId; + SessionSurface.HostSurfaceId = HostSurface.HostSurfaceId; + SessionSurface.LaunchSurfaceId = LaunchSurface.LaunchSurfaceId; + SessionSurface.ViewContextSurfaceId = ViewContextSurface.ViewContextSurfaceId; + SessionSurface.Title = TEXT("Magic120Cell shared-map runtime session surface"); + SessionSurface.Summary = + TEXT("Dedicated-family runtime session surface that merges the Magic120Cell shared-map launch posture with the authored projection, symmetry, visibility, and focus defaults so the executed training session carries the owned higher-dimensional interaction shell rather than only the seed-run bridge."); + SessionSurface.HostMapPath = HostSurface.EffectiveHostMapPath; + SessionSurface.HostMapRouteId = HostSurface.EffectiveHostMapRouteId; + SessionSurface.HostMapLabel = HostSurface.EffectiveHostMapLabel; + SessionSurface.bUsesSharedTrainingMapFallback = HostSurface.bUsesSharedTrainingMapFallback; + SessionSurface.RuntimeModeId = LaunchSurface.RuntimeModeId; + SessionSurface.PrimaryPersistenceBoundaryId = LaunchSurface.PrimaryPersistenceBoundaryId; + SessionSurface.PrimaryViewProfileContractId = + ViewContextSurface.PrimaryViewProfileContractId; + AppendUniqueStrings( + SessionSurface.PersistenceSurfaceTags, + LaunchSurface.PersistenceSurfaceTags); + AppendUniqueStrings( + SessionSurface.InteractionSurfaceTags, + LaunchSurface.InteractionSurfaceTags); + AppendUniqueStrings( + SessionSurface.ViewSurfaceTags, + LaunchSurface.ViewSurfaceTags); + AppendUniqueStrings( + SessionSurface.ViewSurfaceTags, + ViewContextSurface.ProjectionSurfaceTags); + AppendUniqueStrings( + SessionSurface.ViewSurfaceTags, + ViewContextSurface.ContextSurfaceTags); + AppendUniqueStrings( + SessionSurface.ViewSurfaceTags, + ViewContextSurface.FocusSurfaceTags); + SessionSurface.SessionTags = + { + TEXT("phase6c"), + TEXT("higher-dimensional"), + TEXT("session-surface"), + TEXT("family:magic120cell"), + TEXT("host:shared-training-map"), + TEXT("session-defaults:launch-plus-view-context"), + FString::Printf(TEXT("activation-profile:%s"), + *LaunchSurface.ActivationProfileId.ToLower()), + FString::Printf(TEXT("host-surface:%s"), + *HostSurface.HostSurfaceId.ToLower()), + FString::Printf(TEXT("launch-surface:%s"), + *LaunchSurface.LaunchSurfaceId.ToLower()), + FString::Printf(TEXT("view-context-surface:%s"), + *ViewContextSurface.ViewContextSurfaceId.ToLower()) + }; + AppendUniqueStrings(SessionSurface.SessionTags, HostSurface.HostTags); + AppendUniqueStrings(SessionSurface.SessionTags, LaunchSurface.LaunchTags); + AppendUniqueStrings(SessionSurface.SessionTags, ViewContextSurface.ViewTags); + AppendUniqueStrings( + SessionSurface.SessionTags, + SessionSurface.PersistenceSurfaceTags); + AppendUniqueStrings( + SessionSurface.SessionTags, + SessionSurface.InteractionSurfaceTags); + AppendUniqueStrings(SessionSurface.SessionTags, SessionSurface.ViewSurfaceTags); + AppendUniqueSelectors(SessionSurface.Selectors, LaunchSurface.Selectors); + AppendUniqueSelectors(SessionSurface.Selectors, ViewContextSurface.Selectors); + AppendUniqueSelectorChoices( + SessionSurface.DefaultSelectorChoices, + LaunchSurface.DefaultSelectorChoices); + AppendUniqueSelectorChoices( + SessionSurface.DefaultSelectorChoices, + ViewContextSurface.DefaultSelectorChoices); + SessionSurface.SourceAttribution = MakeSessionAttribution( + SessionSurface.SessionSurfaceId, + TEXT("Phase 6C dedicated-family runtime session surface for Magic120Cell that turns the authored launch and view-context posture into one executed clean-room session contract while the shared training-map host remains the effective runtime fallback.") + ); + return SessionSurface; + } + + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface BuildMagicCube5DSessionSurface() + { + FHyperTwistTrainingHigherDimensionalRuntimeLaunchSurface LaunchSurface; + if (!UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryGetRuntimeLaunchSurfaceByActivationProfileId( + UHyperTwistTrainingHigherDimensionalRuntimeLibrary::BuildBundledHigherDimensionalRuntimeLaunchCatalog(), + TEXT("magiccube5d-cleanroom-runtime-activation"), + LaunchSurface)) + { + return FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); + } + + FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface ViewContextSurface; + if (!UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryGetRuntimeViewContextSurfaceByActivationProfileId( + UHyperTwistTrainingHigherDimensionalRuntimeLibrary::BuildBundledHigherDimensionalRuntimeViewContextCatalog(), + LaunchSurface.ActivationProfileId, + ViewContextSurface)) + { + return FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); + } + + FHyperTwistTrainingHigherDimensionalRuntimeHostSurface HostSurface; + if (!UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryGetRuntimeHostSurfaceByActivationProfileId( + UHyperTwistTrainingHigherDimensionalRuntimeLibrary::BuildBundledHigherDimensionalRuntimeHostCatalog(), + LaunchSurface.ActivationProfileId, + HostSurface)) + { + return FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); + } + + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface SessionSurface; + SessionSurface.SessionSurfaceId = + TEXT("phase6c/magiccube5d/shared-training-session-surface"); + SessionSurface.ActivationProfileId = LaunchSurface.ActivationProfileId; + SessionSurface.HostSurfaceId = HostSurface.HostSurfaceId; + SessionSurface.LaunchSurfaceId = LaunchSurface.LaunchSurfaceId; + SessionSurface.ViewContextSurfaceId = ViewContextSurface.ViewContextSurfaceId; + SessionSurface.Title = TEXT("MagicCube5D shared-map runtime session surface"); + SessionSurface.Summary = + TEXT("Dedicated-family runtime session surface that merges the MagicCube5D shared-map launch posture with the authored projection, stereo, visibility, and focus defaults so the executed training session carries the owned higher-dimensional interaction shell rather than only the seed-run bridge."); + SessionSurface.HostMapPath = HostSurface.EffectiveHostMapPath; + SessionSurface.HostMapRouteId = HostSurface.EffectiveHostMapRouteId; + SessionSurface.HostMapLabel = HostSurface.EffectiveHostMapLabel; + SessionSurface.bUsesSharedTrainingMapFallback = HostSurface.bUsesSharedTrainingMapFallback; + SessionSurface.RuntimeModeId = LaunchSurface.RuntimeModeId; + SessionSurface.PrimaryPersistenceBoundaryId = LaunchSurface.PrimaryPersistenceBoundaryId; + SessionSurface.PrimaryViewProfileContractId = + ViewContextSurface.PrimaryViewProfileContractId; + AppendUniqueStrings( + SessionSurface.PersistenceSurfaceTags, + LaunchSurface.PersistenceSurfaceTags); + AppendUniqueStrings( + SessionSurface.InteractionSurfaceTags, + LaunchSurface.InteractionSurfaceTags); + AppendUniqueStrings( + SessionSurface.ViewSurfaceTags, + LaunchSurface.ViewSurfaceTags); + AppendUniqueStrings( + SessionSurface.ViewSurfaceTags, + ViewContextSurface.ProjectionSurfaceTags); + AppendUniqueStrings( + SessionSurface.ViewSurfaceTags, + ViewContextSurface.ContextSurfaceTags); + AppendUniqueStrings( + SessionSurface.ViewSurfaceTags, + ViewContextSurface.FocusSurfaceTags); + SessionSurface.SessionTags = + { + TEXT("phase6c"), + TEXT("higher-dimensional"), + TEXT("session-surface"), + TEXT("family:magiccube5d"), + TEXT("host:shared-training-map"), + TEXT("session-defaults:launch-plus-view-context"), + FString::Printf(TEXT("activation-profile:%s"), + *LaunchSurface.ActivationProfileId.ToLower()), + FString::Printf(TEXT("host-surface:%s"), + *HostSurface.HostSurfaceId.ToLower()), + FString::Printf(TEXT("launch-surface:%s"), + *LaunchSurface.LaunchSurfaceId.ToLower()), + FString::Printf(TEXT("view-context-surface:%s"), + *ViewContextSurface.ViewContextSurfaceId.ToLower()) + }; + AppendUniqueStrings(SessionSurface.SessionTags, HostSurface.HostTags); + AppendUniqueStrings(SessionSurface.SessionTags, LaunchSurface.LaunchTags); + AppendUniqueStrings(SessionSurface.SessionTags, ViewContextSurface.ViewTags); + AppendUniqueStrings( + SessionSurface.SessionTags, + SessionSurface.PersistenceSurfaceTags); + AppendUniqueStrings( + SessionSurface.SessionTags, + SessionSurface.InteractionSurfaceTags); + AppendUniqueStrings(SessionSurface.SessionTags, SessionSurface.ViewSurfaceTags); + AppendUniqueSelectors(SessionSurface.Selectors, LaunchSurface.Selectors); + AppendUniqueSelectors(SessionSurface.Selectors, ViewContextSurface.Selectors); + AppendUniqueSelectorChoices( + SessionSurface.DefaultSelectorChoices, + LaunchSurface.DefaultSelectorChoices); + AppendUniqueSelectorChoices( + SessionSurface.DefaultSelectorChoices, + ViewContextSurface.DefaultSelectorChoices); + SessionSurface.SourceAttribution = MakeSessionAttribution( + SessionSurface.SessionSurfaceId, + TEXT("Phase 6C dedicated-family runtime session surface for MagicCube5D that turns the authored launch and view-context posture into one executed clean-room session contract while the shared training-map host remains the effective runtime fallback.") + ); + return SessionSurface; + } } FHyperTwistTrainingHigherDimensionalRuntimeActivationCatalog @@ -1074,21 +1363,32 @@ bool UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryBuildTrainingDeckFro return false; } + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface SessionSurface; + if (!TryGetRuntimeSessionSurfaceByActivationProfileId( + BuildBundledHigherDimensionalRuntimeSessionCatalog(), + LaunchSurface.ActivationProfileId, + SessionSurface)) + { + return false; + } + FHyperTwistTrainingImportedRuntimeSurface RuntimeSurface; RuntimeSurface.SurfaceKind = LaunchSurface.SurfaceKind; RuntimeSurface.SurfaceId = LaunchSurface.SurfaceId; RuntimeSurface.SurfaceLabel = LaunchSurface.SurfaceLabel; RuntimeSurface.RuntimeModeId = LaunchSurface.RuntimeModeId; RuntimeSurface.GeneratorType = LaunchSurface.GeneratorType; - RuntimeSurface.Selectors = LaunchSurface.Selectors; + RuntimeSurface.Selectors = SessionSurface.Selectors; RuntimeSurface.OriginPaths = { + SessionSurface.SessionSurfaceId, + SessionSurface.ViewContextSurfaceId, LaunchSurface.LaunchSurfaceId, LaunchSurface.HostSurfaceId, LaunchSurface.HostMapPath, LaunchSurface.HostMapRouteId }; - RuntimeSurface.Notes = LaunchSurface.Summary; + RuntimeSurface.Notes = SessionSurface.Summary; FHyperTwistTrainingCase SeedCase; SeedCase.CaseId = LaunchSurface.SeedCaseId; @@ -1110,13 +1410,17 @@ bool UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryBuildTrainingDeckFro SeedCase.Tags, LaunchSurface.LaunchTags ); + HyperTwistTrainingHigherDimensionalRuntimeLibraryInternal::AppendUniqueStrings( + SeedCase.Tags, + SessionSurface.SessionTags + ); SeedCase.AllowedDeliveryModes = {EHyperTwistTrainingDeliveryMode::VirtualCube}; - SeedCase.SourceAttribution = LaunchSurface.SourceAttribution; + SeedCase.SourceAttribution = SessionSurface.SourceAttribution; SeedCase.SourceAttribution.SourceDeckId = LaunchSurface.DeckId; SeedCase.SourceAttribution.SourceCaseId = SeedCase.CaseId; OutDeck.DeckId = LaunchSurface.DeckId; - OutDeck.Title = LaunchSurface.Title; + OutDeck.Title = SessionSurface.Title; OutDeck.DeliveryModes = {EHyperTwistTrainingDeliveryMode::VirtualCube}; OutDeck.SelectionPolicy = EHyperTwistTrainingSelectionPolicy::Scripted; OutDeck.bSupportsAlgorithmReveal = false; @@ -1137,7 +1441,11 @@ bool UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryBuildTrainingDeckFro OutDeck.Tags, LaunchSurface.LaunchTags ); - OutDeck.SourceAttribution = LaunchSurface.SourceAttribution; + HyperTwistTrainingHigherDimensionalRuntimeLibraryInternal::AppendUniqueStrings( + OutDeck.Tags, + SessionSurface.SessionTags + ); + OutDeck.SourceAttribution = SessionSurface.SourceAttribution; OutDeck.SourceAttribution.SourceDeckId = LaunchSurface.DeckId; OutDeck.ImportedRuntimeSurface = RuntimeSurface; return OutDeck.IsStructurallyValid() @@ -1208,3 +1516,65 @@ bool UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryGetRuntimeViewContex OutViewContextSurface ); } + +FHyperTwistTrainingHigherDimensionalRuntimeSessionCatalog +UHyperTwistTrainingHigherDimensionalRuntimeLibrary::BuildBundledHigherDimensionalRuntimeSessionCatalog() +{ + FHyperTwistTrainingHigherDimensionalRuntimeSessionCatalog Catalog; + Catalog.SessionSurfaces = + { + HyperTwistTrainingHigherDimensionalRuntimeLibraryInternal::BuildMagic120CellSessionSurface(), + HyperTwistTrainingHigherDimensionalRuntimeLibraryInternal::BuildMagicCube5DSessionSurface() + }; + return Catalog; +} + +bool UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryGetRuntimeSessionSurfaceByActivationProfileId( + const FHyperTwistTrainingHigherDimensionalRuntimeSessionCatalog& Catalog, + const FString& ActivationProfileId, + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& OutSessionSurface +) +{ + if (ActivationProfileId.IsEmpty()) + { + OutSessionSurface = FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); + return false; + } + + for (const FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& SessionSurface : + Catalog.SessionSurfaces) + { + if (SessionSurface.ActivationProfileId.Equals(ActivationProfileId, ESearchCase::IgnoreCase)) + { + OutSessionSurface = SessionSurface; + return true; + } + } + + OutSessionSurface = FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); + return false; +} + +bool UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryGetRuntimeSessionSurfaceByPuzzleId( + const FHyperTwistTrainingHigherDimensionalRuntimeSessionCatalog& Catalog, + const FString& PuzzleId, + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& OutSessionSurface +) +{ + FHyperTwistTrainingHigherDimensionalRuntimeActivationProfile Profile; + if (PuzzleId.IsEmpty() + || !TryGetRuntimeActivationProfileByPuzzleId( + BuildBundledHigherDimensionalRuntimeActivationCatalog(), + PuzzleId, + Profile)) + { + OutSessionSurface = FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); + return false; + } + + return TryGetRuntimeSessionSurfaceByActivationProfileId( + Catalog, + Profile.ActivationProfileId, + OutSessionSurface + ); +} diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp index 7c15030..571bbfe 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp @@ -156,6 +156,13 @@ void UHyperTwistTrainingPanelWidget::RefreshTrainingState() CachedHigherDimensionalRuntimeViewContextSurface = FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface(); } + if (!UHyperTwistTrainingRuntimeLibrary::TryGetActiveHigherDimensionalRuntimeSessionSurface( + this, + CachedHigherDimensionalRuntimeSessionSurface)) + { + CachedHigherDimensionalRuntimeSessionSurface = + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); + } CachedMethodDrillRunState = UHyperTwistTrainingRuntimeLibrary::GetActiveMethodDrillRunState(this); CachedMethodDrillSummary = UHyperTwistTrainingRuntimeLibrary::GetActiveMethodDrillSummary(this); CachedMethodDrillDiagnosticPacket = @@ -471,6 +478,17 @@ UHyperTwistTrainingPanelWidget::GetDisplayedHigherDimensionalRuntimeViewContextS return CachedHigherDimensionalRuntimeViewContextSurface; } +bool UHyperTwistTrainingPanelWidget::HasDisplayedHigherDimensionalRuntimeSessionSurface() const +{ + return CachedHigherDimensionalRuntimeSessionSurface.IsStructurallyValid(); +} + +FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface +UHyperTwistTrainingPanelWidget::GetDisplayedHigherDimensionalRuntimeSessionSurface() const +{ + return CachedHigherDimensionalRuntimeSessionSurface; +} + FHyperTwistTrainingDeck UHyperTwistTrainingPanelWidget::BuildActiveCoachRecommendedDeck(const int32 MaxCases) { CachedCoachRecommendedDeck = UHyperTwistTrainingRuntimeLibrary::BuildActiveCoachRecommendedDeck( diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.cpp index 0f6385a..bf1be37 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.cpp @@ -276,6 +276,25 @@ namespace HyperTwistTrainingRuntimeLibraryInternal OutViewContextSurface ); } + + bool TryResolveHigherDimensionalRuntimeSessionSurface( + const FHyperTwistTrainingRunState& RunState, + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& OutSessionSurface + ) + { + FHyperTwistTrainingHigherDimensionalRuntimeActivationProfile ActivationProfile; + if (!TryResolveHigherDimensionalRuntimeActivationProfile(RunState, ActivationProfile)) + { + OutSessionSurface = FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); + return false; + } + + return UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryGetRuntimeSessionSurfaceByActivationProfileId( + UHyperTwistTrainingHigherDimensionalRuntimeLibrary::BuildBundledHigherDimensionalRuntimeSessionCatalog(), + ActivationProfile.ActivationProfileId, + OutSessionSurface + ); + } } UHyperTwistTrainingSubsystem* UHyperTwistTrainingRuntimeLibrary::GetTrainingSubsystem(UObject* WorldContextObject) @@ -703,6 +722,12 @@ UHyperTwistTrainingRuntimeLibrary::GetBundledHigherDimensionalRuntimeViewContext return UHyperTwistTrainingHigherDimensionalRuntimeLibrary::BuildBundledHigherDimensionalRuntimeViewContextCatalog(); } +FHyperTwistTrainingHigherDimensionalRuntimeSessionCatalog +UHyperTwistTrainingRuntimeLibrary::GetBundledHigherDimensionalRuntimeSessionCatalog() +{ + return UHyperTwistTrainingHigherDimensionalRuntimeLibrary::BuildBundledHigherDimensionalRuntimeSessionCatalog(); +} + FHyperTwistTrainingLearnedSearchReferenceBundle UHyperTwistTrainingRuntimeLibrary::GetBundledLearnedSearchReferenceBundle() { @@ -7347,6 +7372,41 @@ bool UHyperTwistTrainingRuntimeLibrary::TryGetHigherDimensionalRuntimeViewContex ); } +bool UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalRuntimeSessionSurfaceByActivationProfileId( + const FString& ActivationProfileId, + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& OutSessionSurface +) +{ + return UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryGetRuntimeSessionSurfaceByActivationProfileId( + GetBundledHigherDimensionalRuntimeSessionCatalog(), + ActivationProfileId, + OutSessionSurface + ); +} + +bool UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalRuntimeSessionSurfaceByPuzzleId( + const FString& PuzzleId, + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& OutSessionSurface +) +{ + return UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryGetRuntimeSessionSurfaceByPuzzleId( + GetBundledHigherDimensionalRuntimeSessionCatalog(), + PuzzleId, + OutSessionSurface + ); +} + +bool UHyperTwistTrainingRuntimeLibrary::TryGetHigherDimensionalRuntimeSessionSurfaceForRunState( + const FHyperTwistTrainingRunState& RunState, + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& OutSessionSurface +) +{ + return HyperTwistTrainingRuntimeLibraryInternal::TryResolveHigherDimensionalRuntimeSessionSurface( + RunState, + OutSessionSurface + ); +} + bool UHyperTwistTrainingRuntimeLibrary::TryGetActiveHigherDimensionalRuntimeHostSurface( UObject* WorldContextObject, FHyperTwistTrainingHigherDimensionalRuntimeHostSurface& OutHostSurface @@ -7380,6 +7440,17 @@ bool UHyperTwistTrainingRuntimeLibrary::TryGetActiveHigherDimensionalRuntimeView ); } +bool UHyperTwistTrainingRuntimeLibrary::TryGetActiveHigherDimensionalRuntimeSessionSurface( + UObject* WorldContextObject, + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& OutSessionSurface +) +{ + return TryGetHigherDimensionalRuntimeSessionSurfaceForRunState( + GetActiveTrainingRunState(WorldContextObject), + OutSessionSurface + ); +} + bool UHyperTwistTrainingRuntimeLibrary::TryStartHigherDimensionalLaunchSurface( UObject* WorldContextObject, const FString& ActivationProfileId, diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp index 8ab97a7..bb0f672 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp @@ -256,6 +256,13 @@ void AHyperTwistTrainingSessionActor::RefreshCachedTrainingState() CachedHigherDimensionalRuntimeViewContextSurface = FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface(); } + if (!UHyperTwistTrainingRuntimeLibrary::TryGetActiveHigherDimensionalRuntimeSessionSurface( + this, + CachedHigherDimensionalRuntimeSessionSurface)) + { + CachedHigherDimensionalRuntimeSessionSurface = + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface(); + } CachedActiveTrainingSessionTemplates = UHyperTwistTrainingRuntimeLibrary::GetActiveTrainingSessionTemplates(this); if (AutoStartUserId.IsEmpty()) @@ -444,6 +451,17 @@ AHyperTwistTrainingSessionActor::GetDisplayedHigherDimensionalRuntimeViewContext return CachedHigherDimensionalRuntimeViewContextSurface; } +bool AHyperTwistTrainingSessionActor::HasDisplayedHigherDimensionalRuntimeSessionSurface() const +{ + return CachedHigherDimensionalRuntimeSessionSurface.IsStructurallyValid(); +} + +FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface +AHyperTwistTrainingSessionActor::GetDisplayedHigherDimensionalRuntimeSessionSurface() const +{ + return CachedHigherDimensionalRuntimeSessionSurface; +} + FHyperTwistTrainingDeck AHyperTwistTrainingSessionActor::BuildCoachRecommendedDeck(const int32 MaxCases) { CachedCoachRecommendedDeck = UHyperTwistTrainingRuntimeLibrary::BuildActiveCoachRecommendedDeck( diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp index 0f89fae..83f7ceb 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp @@ -9707,6 +9707,17 @@ bool UHyperTwistTrainingSubsystem::TryStartHigherDimensionalLaunchSurface( return false; } + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface SessionSurface; + if (!UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryGetRuntimeSessionSurfaceByActivationProfileId( + UHyperTwistTrainingHigherDimensionalRuntimeLibrary::BuildBundledHigherDimensionalRuntimeSessionCatalog(), + ActivationProfileId, + SessionSurface)) + { + OutBlockedReason = + TEXT("Higher-dimensional runtime session surface could not be resolved from the activation profile id."); + return false; + } + FHyperTwistTrainingDeck LaunchDeck; if (!UHyperTwistTrainingHigherDimensionalRuntimeLibrary::TryBuildTrainingDeckFromRuntimeLaunchSurface( LaunchSurface, @@ -9737,7 +9748,7 @@ bool UHyperTwistTrainingSubsystem::TryStartHigherDimensionalLaunchSurface( } for (const FHyperTwistTrainingImportedRuntimeSelectorChoice& Choice : - LaunchSurface.DefaultSelectorChoices) + SessionSurface.DefaultSelectorChoices) { OutRunState = ApplyActiveImportedGeneratedModeSelectorChoice( Choice.SelectorId, diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingHigherDimensionalRuntimeLibrary.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingHigherDimensionalRuntimeLibrary.h index 4ce8802..3f26c01 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingHigherDimensionalRuntimeLibrary.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingHigherDimensionalRuntimeLibrary.h @@ -686,6 +686,203 @@ struct FHyperTwistTrainingHigherDimensionalRuntimeViewContextCatalog } }; +USTRUCT(BlueprintType) +struct FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SessionSurfaceId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ActivationProfileId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString HostSurfaceId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString LaunchSurfaceId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ViewContextSurfaceId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Title; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Summary; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString HostMapPath; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString HostMapRouteId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString HostMapLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUsesSharedTrainingMapFallback = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RuntimeModeId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PrimaryPersistenceBoundaryId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString PrimaryViewProfileContractId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray PersistenceSurfaceTags; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray InteractionSurfaceTags; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray ViewSurfaceTags; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray SessionTags; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray Selectors; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray DefaultSelectorChoices; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FHyperTwistTrainingSourceAttribution SourceAttribution; + + bool IsStructurallyValid() const + { + if (SessionSurfaceId.IsEmpty() + || ActivationProfileId.IsEmpty() + || HostSurfaceId.IsEmpty() + || LaunchSurfaceId.IsEmpty() + || ViewContextSurfaceId.IsEmpty() + || Title.IsEmpty() + || HostMapPath.IsEmpty() + || HostMapRouteId.IsEmpty() + || HostMapLabel.IsEmpty() + || RuntimeModeId.IsEmpty() + || PrimaryPersistenceBoundaryId.IsEmpty() + || PrimaryViewProfileContractId.IsEmpty() + || !SourceAttribution.IsStructurallyValid() + || Selectors.Num() == 0 + || DefaultSelectorChoices.Num() == 0) + { + return false; + } + + TSet SeenSelectorIds; + for (const FHyperTwistTrainingImportedRuntimeSelector& Selector : Selectors) + { + if (!Selector.IsStructurallyValid()) + { + return false; + } + + const FString NormalizedSelectorId = Selector.SelectorId.ToLower(); + if (SeenSelectorIds.Contains(NormalizedSelectorId)) + { + return false; + } + + SeenSelectorIds.Add(NormalizedSelectorId); + } + + TSet SeenChoiceSelectorIds; + for (const FHyperTwistTrainingImportedRuntimeSelectorChoice& Choice : DefaultSelectorChoices) + { + if (!Choice.IsStructurallyValid()) + { + return false; + } + + const FString NormalizedSelectorId = Choice.SelectorId.ToLower(); + if (!SeenSelectorIds.Contains(NormalizedSelectorId) + || SeenChoiceSelectorIds.Contains(NormalizedSelectorId)) + { + return false; + } + + SeenChoiceSelectorIds.Add(NormalizedSelectorId); + } + + return SeenChoiceSelectorIds.Num() == SeenSelectorIds.Num(); + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistTrainingHigherDimensionalRuntimeSessionCatalog +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CatalogId = TEXT("phase6c/higher-dimensional-runtime-session"); + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CatalogVersion = TEXT("2026.06.18"); + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray SessionSurfaces; + + bool IsStructurallyValid() const + { + if (CatalogId.IsEmpty() || CatalogVersion.IsEmpty() || SessionSurfaces.Num() == 0) + { + return false; + } + + TSet SeenSessionSurfaceIds; + TSet SeenActivationProfileIds; + TSet SeenLaunchSurfaceIds; + TSet SeenViewContextSurfaceIds; + for (const FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& SessionSurface : + SessionSurfaces) + { + if (!SessionSurface.IsStructurallyValid()) + { + return false; + } + + const FString NormalizedSessionSurfaceId = SessionSurface.SessionSurfaceId.ToLower(); + if (SeenSessionSurfaceIds.Contains(NormalizedSessionSurfaceId)) + { + return false; + } + + const FString NormalizedActivationProfileId = + SessionSurface.ActivationProfileId.ToLower(); + if (SeenActivationProfileIds.Contains(NormalizedActivationProfileId)) + { + return false; + } + + const FString NormalizedLaunchSurfaceId = SessionSurface.LaunchSurfaceId.ToLower(); + if (SeenLaunchSurfaceIds.Contains(NormalizedLaunchSurfaceId)) + { + return false; + } + + const FString NormalizedViewContextSurfaceId = + SessionSurface.ViewContextSurfaceId.ToLower(); + if (SeenViewContextSurfaceIds.Contains(NormalizedViewContextSurfaceId)) + { + return false; + } + + SeenSessionSurfaceIds.Add(NormalizedSessionSurfaceId); + SeenActivationProfileIds.Add(NormalizedActivationProfileId); + SeenLaunchSurfaceIds.Add(NormalizedLaunchSurfaceId); + SeenViewContextSurfaceIds.Add(NormalizedViewContextSurfaceId); + } + + return true; + } +}; + UCLASS() class UNREALHYPERTWIST_API UHyperTwistTrainingHigherDimensionalRuntimeLibrary : public UBlueprintFunctionLibrary { @@ -783,4 +980,22 @@ public: const FString& PuzzleId, FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface& OutViewContextSurface ); + + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|HigherDimensional") + static FHyperTwistTrainingHigherDimensionalRuntimeSessionCatalog + BuildBundledHigherDimensionalRuntimeSessionCatalog(); + + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|HigherDimensional") + static bool TryGetRuntimeSessionSurfaceByActivationProfileId( + const FHyperTwistTrainingHigherDimensionalRuntimeSessionCatalog& Catalog, + const FString& ActivationProfileId, + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& OutSessionSurface + ); + + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|HigherDimensional") + static bool TryGetRuntimeSessionSurfaceByPuzzleId( + const FHyperTwistTrainingHigherDimensionalRuntimeSessionCatalog& Catalog, + const FString& PuzzleId, + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& OutSessionSurface + ); }; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h index b764ff5..0e54953 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h @@ -123,6 +123,9 @@ public: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|Training|HigherDimensional") FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface CachedHigherDimensionalRuntimeViewContextSurface; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|Training|HigherDimensional") + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface CachedHigherDimensionalRuntimeSessionSurface; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|Training") FHyperTwistTrainingRepositoryRoundTripVerification CachedRepositoryRoundTripVerification; @@ -256,6 +259,13 @@ public: FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface GetDisplayedHigherDimensionalRuntimeViewContextSurface() const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|HigherDimensional") + bool HasDisplayedHigherDimensionalRuntimeSessionSurface() const; + + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|HigherDimensional") + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface + GetDisplayedHigherDimensionalRuntimeSessionSurface() const; + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach") FHyperTwistTrainingDeck BuildActiveCoachRecommendedDeck(int32 MaxCases); diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.h index ac1f52f..20415b5 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.h @@ -213,6 +213,10 @@ public: static FHyperTwistTrainingHigherDimensionalRuntimeViewContextCatalog GetBundledHigherDimensionalRuntimeViewContextCatalog(); + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|HigherDimensional") + static FHyperTwistTrainingHigherDimensionalRuntimeSessionCatalog + GetBundledHigherDimensionalRuntimeSessionCatalog(); + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|LearnedSearch") static FHyperTwistTrainingLearnedSearchReferenceBundle GetBundledLearnedSearchReferenceBundle(); @@ -3478,6 +3482,24 @@ public: FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface& OutViewContextSurface ); + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|HigherDimensional") + static bool TryGetBundledHigherDimensionalRuntimeSessionSurfaceByActivationProfileId( + const FString& ActivationProfileId, + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& OutSessionSurface + ); + + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|HigherDimensional") + static bool TryGetBundledHigherDimensionalRuntimeSessionSurfaceByPuzzleId( + const FString& PuzzleId, + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& OutSessionSurface + ); + + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|HigherDimensional") + static bool TryGetHigherDimensionalRuntimeSessionSurfaceForRunState( + const FHyperTwistTrainingRunState& RunState, + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& OutSessionSurface + ); + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|HigherDimensional", meta = (WorldContext = "WorldContextObject")) static bool TryGetActiveHigherDimensionalRuntimeHostSurface( UObject* WorldContextObject, @@ -3496,6 +3518,12 @@ public: FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface& OutViewContextSurface ); + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|HigherDimensional", meta = (WorldContext = "WorldContextObject")) + static bool TryGetActiveHigherDimensionalRuntimeSessionSurface( + UObject* WorldContextObject, + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface& OutSessionSurface + ); + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|HigherDimensional", meta = (WorldContext = "WorldContextObject")) static bool TryStartHigherDimensionalLaunchSurface( UObject* WorldContextObject, diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h index 41a531b..7471ab9 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h @@ -110,6 +110,9 @@ public: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|Training|HigherDimensional") FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface CachedHigherDimensionalRuntimeViewContextSurface; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|Training|HigherDimensional") + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface CachedHigherDimensionalRuntimeSessionSurface; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|Training") FHyperTwistTrainingRepositoryRoundTripVerification CachedRepositoryRoundTripVerification; @@ -233,6 +236,13 @@ public: FHyperTwistTrainingHigherDimensionalRuntimeViewContextSurface GetDisplayedHigherDimensionalRuntimeViewContextSurface() const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|HigherDimensional") + bool HasDisplayedHigherDimensionalRuntimeSessionSurface() const; + + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|HigherDimensional") + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface + GetDisplayedHigherDimensionalRuntimeSessionSurface() const; + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach") FHyperTwistTrainingDeck BuildCoachRecommendedDeck(int32 MaxCases); diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistHigherDimensionalPhase6CActivationContractTest.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistHigherDimensionalPhase6CActivationContractTest.cpp index 72e5859..df82f34 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistHigherDimensionalPhase6CActivationContractTest.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistHigherDimensionalPhase6CActivationContractTest.cpp @@ -339,6 +339,96 @@ bool FHyperTwistHigherDimensionalPhase6CViewContextCatalogTest::RunTest(const FS return true; } +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistHigherDimensionalPhase6CSessionCatalogTest, + "HyperTwist.FirstParty.HigherDimensional.Phase6C.SessionCatalog", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistHigherDimensionalPhase6CSessionCatalogTest::RunTest(const FString& Parameters) +{ + const FHyperTwistTrainingHigherDimensionalRuntimeSessionCatalog Catalog = + UHyperTwistTrainingRuntimeLibrary::GetBundledHigherDimensionalRuntimeSessionCatalog(); + + TestTrue( + TEXT("The Phase 6C higher-dimensional session catalog must be structurally valid."), + Catalog.IsStructurallyValid() + ); + TestEqual( + TEXT("The Phase 6C higher-dimensional session catalog must expose both retained family session surfaces."), + Catalog.SessionSurfaces.Num(), + 2 + ); + + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface Magic120CellSessionSurface; + TestTrue( + TEXT("The Magic120Cell session surface must resolve from the bundled catalog."), + UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalRuntimeSessionSurfaceByActivationProfileId( + TEXT("magic120cell-cleanroom-runtime-activation"), + Magic120CellSessionSurface + ) + ); + TestEqual( + TEXT("The Magic120Cell session surface must preserve the launch surface linkage."), + Magic120CellSessionSurface.LaunchSurfaceId, + TEXT("phase6c/magic120cell/shared-training-launch-surface") + ); + TestEqual( + TEXT("The Magic120Cell session surface must preserve the view-context linkage."), + Magic120CellSessionSurface.ViewContextSurfaceId, + TEXT("phase6c/magic120cell/shared-training-view-context-surface") + ); + TestEqual( + TEXT("The Magic120Cell session surface must merge all unique launch and view selector families."), + Magic120CellSessionSurface.Selectors.Num(), + 7 + ); + TestEqual( + TEXT("The Magic120Cell session surface must merge all unique default selector choices."), + Magic120CellSessionSurface.DefaultSelectorChoices.Num(), + 7 + ); + TestTrue( + TEXT("The Magic120Cell session surface must mark the merged session-default posture."), + Magic120CellSessionSurface.SessionTags.Contains(TEXT("session-defaults:launch-plus-view-context")) + ); + + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface MagicCube5DSessionSurface; + TestTrue( + TEXT("The MagicCube5D session surface must resolve from the bundled catalog."), + UHyperTwistTrainingRuntimeLibrary::TryGetBundledHigherDimensionalRuntimeSessionSurfaceByPuzzleId( + TEXT("hypercube/magiccube5d/order3"), + MagicCube5DSessionSurface + ) + ); + TestEqual( + TEXT("The MagicCube5D session surface must preserve the launch surface linkage."), + MagicCube5DSessionSurface.LaunchSurfaceId, + TEXT("phase6c/magiccube5d/shared-training-launch-surface") + ); + TestEqual( + TEXT("The MagicCube5D session surface must preserve the view-context linkage."), + MagicCube5DSessionSurface.ViewContextSurfaceId, + TEXT("phase6c/magiccube5d/shared-training-view-context-surface") + ); + TestEqual( + TEXT("The MagicCube5D session surface must merge duplicate stereo and visibility selectors rather than duplicating them."), + MagicCube5DSessionSurface.Selectors.Num(), + 5 + ); + TestEqual( + TEXT("The MagicCube5D session surface must preserve one default choice per merged selector."), + MagicCube5DSessionSurface.DefaultSelectorChoices.Num(), + 5 + ); + TestEqual( + TEXT("The MagicCube5D session surface must stay on the shared host fallback."), + MagicCube5DSessionSurface.HostMapPath, + TEXT("/Game/HyperTwistTraining/Maps/L_HyperTwist_ClassicTraining") + ); + return true; +} + IMPLEMENT_SIMPLE_AUTOMATION_TEST( FHyperTwistHigherDimensionalPhase6CMagic120CellActivationProfileTest, "HyperTwist.FirstParty.HigherDimensional.Phase6C.Magic120CellActivationProfile", @@ -586,10 +676,25 @@ bool FHyperTwistHigherDimensionalPhase6CLaunchExecutionTest::RunTest(const FStri StartedRunState.ImportedGeneratedModeLaunchRequest.LaunchConfig.SurfaceId, TEXT("phase6c/magiccube5d/generated-runtime-surface") ); + TestEqual( + TEXT("The launch-execution proof must persist the merged higher-dimensional selector posture."), + StartedRunState.ImportedGeneratedModeLaunchRequest.LaunchConfig.SelectorChoices.Num(), + 5 + ); TestTrue( TEXT("The launch-execution proof must preserve the generated-mode execution tag."), StartedRunState.ActiveDeck.Tags.Contains(TEXT("generated-mode:owned-execution")) ); + TestEqual( + TEXT("The launch-execution proof must keep the merged runtime surface selector set on the active deck."), + StartedRunState.ActiveDeck.ImportedRuntimeSurface.Selectors.Num(), + 5 + ); + TestEqual( + TEXT("The launch-execution proof must keep the merged selector posture on the active run-state selection state."), + StartedRunState.ImportedRuntimeSelectionState.SelectorChoices.Num(), + 5 + ); FHyperTwistTrainingHigherDimensionalRuntimeActivationProfile ActivationProfile; TestTrue( @@ -684,6 +789,31 @@ bool FHyperTwistHigherDimensionalPhase6CLaunchExecutionTest::RunTest(const FStri ViewContextSurface.DefaultSelectorChoices.Num(), 4 ); + + FHyperTwistTrainingHigherDimensionalRuntimeSessionSurface SessionSurface; + TestTrue( + TEXT("The launch-execution proof must resolve the active higher-dimensional session surface."), + UHyperTwistTrainingRuntimeLibrary::TryGetHigherDimensionalRuntimeSessionSurfaceForRunState( + StartedRunState, + SessionSurface + ) + ); + TestEqual( + TEXT("The launch-execution proof must preserve the resolved session surface id."), + SessionSurface.SessionSurfaceId, + TEXT("phase6c/magiccube5d/shared-training-session-surface") + ); + TestEqual( + TEXT("The launch-execution proof must preserve the merged session selector count."), + SessionSurface.DefaultSelectorChoices.Num(), + 5 + ); + TestTrue( + TEXT("The launch-execution proof must record the explicit higher-dimensional session surface in runtime lineage."), + StartedRunState.ActiveDeck.ImportedRuntimeSurface.OriginPaths.Contains( + TEXT("phase6c/magiccube5d/shared-training-session-surface") + ) + ); return true; } diff --git a/docs/ops/HYPERTWIST_COMPREHENSIVE_RECONSTRUCTION_ROADMAP_2026-06-10.md b/docs/ops/HYPERTWIST_COMPREHENSIVE_RECONSTRUCTION_ROADMAP_2026-06-10.md index b545373..4a60f09 100644 --- a/docs/ops/HYPERTWIST_COMPREHENSIVE_RECONSTRUCTION_ROADMAP_2026-06-10.md +++ b/docs/ops/HYPERTWIST_COMPREHENSIVE_RECONSTRUCTION_ROADMAP_2026-06-10.md @@ -359,6 +359,8 @@ Closure read: - `2026-06-18` Windows checkpoint: after recovering an interrupted follow-up and re-proving the primary reverse-SSH lane, the same isolated worktree `C:\HyperTwist_worktrees\phase10validate` rebuilt the cleaned slice with `Result: Succeeded` / UnrealBuildTool `Total execution time: 124.81 seconds`, and targeted `UnrealEditor-Cmd` automation found `8` tests under `HyperTwist.FirstParty.HigherDimensional.Phase6C` and passed all `8`, including `LaunchCatalog`, `ViewContextCatalog`, `LaunchExecution`, and `RunStateActivationResolution`; the commandlet emitted `Ignoring very large delta of 499.13 seconds` during `LaunchExecution`, so that quiet interval is now known-good rather than a corruption signal - `2026-06-18` continuation proof: current code now adds an explicit higher-dimensional host-surface catalog that records the preferred dedicated-family `Magic120Cell` / `MagicCube5D` host-map targets while keeping the current shared training-map host as the effective fallback, then mirrors that resolved host surface through the training runtime library plus the live training panel/session-actor caches and the launch/view-context surfaces themselves - `2026-06-18` Windows checkpoint: the same isolated worktree `C:\HyperTwist_worktrees\phase10validate` rebuilt the widened host-surface slice with `Result: Succeeded` / UnrealBuildTool `Total execution time: 2858.02 seconds`, and targeted `UnrealEditor-Cmd` automation found `9` tests under `HyperTwist.FirstParty.HigherDimensional.Phase6C` and passed all `9`, including the new `HostCatalog`; `LaunchExecution` again emitted `Ignoring very large delta of 425.99 seconds`, confirming that long quiet interval remains a known-good characteristic rather than a corruption signal +- `2026-06-18` continuation proof: current code now adds an explicit higher-dimensional runtime-session catalog that merges the launch, host, and view-context seams into one executed family-owned session posture, threads that session surface through the training runtime library plus the live training panel/session-actor caches, and upgrades generated-mode deck lineage and start-time selector application to use the merged launch-plus-view defaults instead of only the narrower launch defaults +- `2026-06-18` Windows checkpoint: the same isolated worktree `C:\HyperTwist_worktrees\phase10validate` rebuilt the widened session-surface slice with `Result: Succeeded` / UnrealBuildTool `Total execution time: 3541.98 seconds`, and targeted `UnrealEditor-Cmd` automation found `10` tests under `HyperTwist.FirstParty.HigherDimensional.Phase6C` and passed all `10`, including the new `SessionCatalog`; `LaunchExecution` emitted `Ignoring very large delta of 573.84 seconds`, so that longer quiet interval also remains confirmed as known-good on this lane rather than a corruption signal - [ ] Implement the full owned interactive `120-cell` and `5D` projection/runtime surfaces in Unreal above the new activation catalog - [ ] Replace the current shared-map execution bridge with full owned dedicated-family interactive launch, map, and persistence surfaces for `120-cell` and `5D` @@ -543,4 +545,12 @@ Recommended next widening order: `localhost:22022` with `9` passing `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests, including the new `HostCatalog` +- `2026-06-18`: the next `Phase 6C` continuation added an explicit + higher-dimensional runtime-session catalog that merges the launch, host, and + view-context seams into one executed family-owned session posture, upgrades + generated-mode lineage plus start-time selector application to use the + merged launch-plus-view defaults, and revalidated the widened slice on + `localhost:22022` with `10` passing + `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests, including the new + `SessionCatalog` - later classic-cube polish only when a concrete presentation gap remains, not as the default next move diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md b/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md index f3a522e..484c3db 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md @@ -270,6 +270,7 @@ repo. | Higher-dimensional clean-room runtime activation catalog | Implemented now | landed `Phase 6C` activation packet | First-party current code now resolves canonical `polychoron/magic120cell` and `hypercube/magiccube5d/order3` puzzle definitions, default launch posture, primary donor-boundary contract ids, and the no-external-process clean-room stance above the retained `Magic120Cell` / `MagicCube5D` contracts and the retained `Hyperspeedcube` runtime anchor. The current continuation also resolves the active higher-dimensional activation profile from live training run state through both puzzle-id and imported generated-mode `RuntimeModeId` paths, then mirrors that resolved profile through the training runtime library plus the training panel/session caches; the primary `localhost:22022` Windows lane passed all `5` `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests on `2026-06-13`. | | Higher-dimensional shared-map launch and view-context execution bridge | Implemented now | landed `Phase 6C` continuation packet | First-party current code now bundles higher-dimensional launch surfaces and view-context surfaces for `Magic120Cell` and `MagicCube5D`, resolves those surfaces through the training runtime library plus the live training panel/session-actor caches, and lets the training subsystem start the shared-map seed run, apply default selector posture, persist the generated-mode launch request, and start the owned generated run without widening into external-process ownership. After recovering an interrupted follow-up, the primary reverse-SSH `localhost:22022` Windows lane rebuilt the cleaned slice on `2026-06-18` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 124.81 seconds`, and passed all `8` `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests, including `LaunchCatalog`, `ViewContextCatalog`, `LaunchExecution`, and `RunStateActivationResolution`; the quiet `LaunchExecution` interval is now known to be healthy rather than a stalled commandlet. | | Higher-dimensional explicit dedicated-host seam | Implemented now | landed `Phase 6C` host-surface continuation packet | First-party current code now records the preferred dedicated-family `Magic120Cell` / `MagicCube5D` host-map targets in an explicit higher-dimensional host-surface catalog while keeping the current shared training map as the effective runtime fallback, mirrors that resolved host seam through the training runtime library plus the panel/session caches, and threads the host-surface id into the launch/view-context surfaces and generated-mode lineage. The primary reverse-SSH `localhost:22022` Windows lane rebuilt this widened slice on `2026-06-18` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 2858.02 seconds`, and passed all `9` `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests, including the new `HostCatalog`; the long `LaunchExecution` quiet interval remained known-good. | +| Higher-dimensional executed runtime session surface | Implemented now | landed `Phase 6C` session-surface continuation packet | First-party current code now merges the higher-dimensional launch, host, and view-context seams into an explicit runtime-session catalog for `Magic120Cell` and `MagicCube5D`, mirrors that session surface through the training runtime library plus the panel/session caches, upgrades generated-mode deck lineage to record the resolved session surface, and applies the merged launch-plus-view selector posture at start time instead of only the narrower launch defaults. The primary reverse-SSH `localhost:22022` Windows lane rebuilt this widened slice on `2026-06-18` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 3541.98 seconds`, and passed all `10` `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests, including the new `SessionCatalog`; the longer `LaunchExecution` quiet interval of `573.84 seconds` remained known-good. | | Broad non-Euclidean interaction shell and host ownership | Deep-source grounded retained | `MagicTile` retained remainder | Broad interaction-shell, WinForms/OpenTK host ownership, and generic runtime replacement remain deferred after the landed `Phase 6R-T` slice. | ### 7. Speech input and voice sidecars diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md b/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md index 7faa84e..1370b08 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md @@ -139,9 +139,18 @@ Current consolidated milestone snapshot: Succeeded`, UnrealBuildTool `Total execution time: 2858.02 seconds`, and passed all `9` `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests, including the new `HostCatalog` +- `2026-06-18`: the next `Phase 6C` continuation added an explicit + higher-dimensional runtime-session catalog that merges the launch, host, and + view-context seams into one executed family-owned session posture, upgrades + generated-mode lineage plus start-time selector application to use the + merged launch-plus-view defaults, and revalidated the widened slice on the + same `localhost:22022` lane with `Result: Succeeded`, UnrealBuildTool + `Total execution time: 3541.98 seconds`, and all `10` + `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests passing, including + the new `SessionCatalog` - the remaining `Phase 6C` gap is now the full dedicated interactive - `120-cell` / `5D` runtime and map replacement, not the shared-map execution - bridge or the current active-run proof + `120-cell` / `5D` runtime and map replacement, not selector/view default + activation, the shared-map execution bridge, or the current active-run proof - the canonical HyperTwist repo-row portfolio is now treated as `75` rows, not `71` - currently implemented rows are now `35`, not `20`