From 33661fe8a23fa2f9e2ca3db8dfe04592673b459a Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Sat, 9 May 2026 01:30:27 +0200 Subject: [PATCH] Expose gameplay selector merged roster phase-id lookup --- .../HyperTwistTrainingCoachLibrary.cpp | 230 ++++++++++++++++++ .../HyperTwistTrainingPanelWidget.cpp | 21 ++ .../HyperTwistTrainingSessionActor.cpp | 21 ++ .../HyperTwistTrainingCoachLibrary.h | 11 + .../HyperTwistTrainingPanelWidget.h | 7 + .../HyperTwistTrainingSessionActor.h | 7 + .../HyperTwistTrainingTypes.h | 115 +++++++++ ...RTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md | 4 +- ...OOKUP_INSPECT_SURFACE_PACKET_2026-05-09.md | 33 +++ 9 files changed, 447 insertions(+), 2 deletions(-) create mode 100644 docs/arch/HYPERTWIST_PHASE4_GAMEPLAY_GENERATED_MODE_SELECTOR_OPTION_OWNED_EXECUTION_SPLIT_PHASE_CURRENT_SELECTION_LABEL_PROVENANCE_PARTITION_MERGED_ORDERED_ROSTER_PHASE_ID_LOOKUP_INSPECT_SURFACE_PACKET_2026-05-09.md diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp index e50bd46..905c179 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp @@ -12779,6 +12779,236 @@ UHyperTwistTrainingCoachLibrary:: return Surface; } +FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface +UHyperTwistTrainingCoachLibrary:: + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface( + const FHyperTwistTrainingRunState& RunState, + const FString& SelectorId, + const FString& PhaseId, + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface& OptionMenuSurface, + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface& + OptionLaunchRequestPreviewSurface + ) +{ + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterInspectSurface + MergedOrderedRosterSurface = + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterInspectSurface( + RunState, + SelectorId, + OptionMenuSurface, + OptionLaunchRequestPreviewSurface + ); + + FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface + Surface; + Surface.SelectorId = MergedOrderedRosterSurface.SelectorId; + Surface.SelectorLabel = MergedOrderedRosterSurface.SelectorLabel; + Surface.BindingLabel = MergedOrderedRosterSurface.BindingLabel; + Surface.Headline = + TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Current-Selection Label-Provenance Partition Merged Ordered Roster Phase-Id Lookup Inspect"); + Surface.bHasSelector = MergedOrderedRosterSurface.bHasSelector; + Surface.bHasSelection = MergedOrderedRosterSurface.bHasSelection; + Surface.bSelectionMatchesAvailableOption = + MergedOrderedRosterSurface.bSelectionMatchesAvailableOption; + Surface.CurrentSelectionSelectionLine = + MergedOrderedRosterSurface.CurrentSelectionSelectionLine; + Surface.LookupPhaseId = PhaseId; + Surface.bHasLookupPhaseId = !PhaseId.IsEmpty(); + Surface.MergedOrderedPhaseCountLine = + MergedOrderedRosterSurface.MergedOrderedPhaseCountLine; + Surface.CurrentSelectionOptionId = + MergedOrderedRosterSurface.CurrentSelectionOptionId; + Surface.CurrentSelectionOptionLabel = + MergedOrderedRosterSurface.CurrentSelectionOptionLabel; + Surface.CurrentSelectionOptionValue = + MergedOrderedRosterSurface.CurrentSelectionOptionValue; + Surface.LaunchRequestPreviewKind = + MergedOrderedRosterSurface.LaunchRequestPreviewKind; + Surface.bStartsOwnedCaseImmediately = + MergedOrderedRosterSurface.bStartsOwnedCaseImmediately; + Surface.bRetainsActiveDeckSplitPhaseFusion = + MergedOrderedRosterSurface.bRetainsActiveDeckSplitPhaseFusion; + Surface.bPreviewBlocked = MergedOrderedRosterSurface.bPreviewBlocked; + Surface.bCanPreview = MergedOrderedRosterSurface.bCanPreview; + + if (!SelectorId.IsEmpty()) + { + const FString SelectorHeadlineValue = OptionMenuSurface.SelectorLabel.IsEmpty() + ? SelectorId + : OptionMenuSurface.SelectorLabel; + Surface.Headline = Surface.bHasLookupPhaseId + ? FString::Printf( + TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Current-Selection Label-Provenance Partition Merged Ordered Roster Phase-Id Lookup Inspect: %s [%s]"), + *SelectorHeadlineValue, + *PhaseId + ) + : FString::Printf( + TEXT("Generated Mode Selector Option Owned-Execution Split-Phase Current-Selection Label-Provenance Partition Merged Ordered Roster Phase-Id Lookup Inspect: %s"), + *SelectorHeadlineValue + ); + } + + if (Surface.bHasLookupPhaseId) + { + if (const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterInspectPhaseSurface* + MatchedPhase = MergedOrderedRosterSurface.MergedOrderedPhases.FindByPredicate( + [&PhaseId]( + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterInspectPhaseSurface& PhaseSurface + ) + { + return PhaseSurface.PhaseId == PhaseId; + } + )) + { + Surface.MatchedPhase = *MatchedPhase; + Surface.MatchedNormalizedOrder = MatchedPhase->NormalizedOrder; + Surface.bHasCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookup = + true; + Surface.bHasExactCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookup = + MergedOrderedRosterSurface.bHasExactCurrentSelectionLabelProvenancePartitionMergedOrderedRoster; + Surface.bMatchedExplicitLabelPartition = + MatchedPhase->bBelongsToExplicitLabelPartition; + Surface.bMatchedFallbackLabelPartition = + MatchedPhase->bBelongsToFallbackLabelPartition; + Surface.CurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupLine = + FString::Printf( + TEXT("Current-selection merged ordered phase-id lookup on execute: phase id %s resolves to normalized phase #%d with label %s."), + *MatchedPhase->PhaseId, + MatchedPhase->NormalizedOrder, + *MatchedPhase->NormalizedLabel + ); + Surface.MatchedPhaseOrderLine = MatchedPhase->OrderLine; + Surface.MatchedPhaseLabelLine = MatchedPhase->LabelLine; + Surface.MatchedPhasePartitionLine = + MatchedPhase->LabelProvenancePartitionLine; + } + } + + if (Surface.bHasCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookup) + { + Surface.StatusLine = FString::Printf( + TEXT("Generated-mode selector option owned-execution split-phase current-selection merged ordered roster phase-id lookup inspect exposes retained phase id %s for the active selection."), + *Surface.LookupPhaseId + ); + } + else if (!Surface.bHasLookupPhaseId) + { + Surface.CurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupLine = + TEXT("Current-selection merged ordered phase-id lookup on execute: no phase id requested."); + Surface.MatchedPhaseOrderLine = + TEXT("Requested phase order on execute: unavailable"); + Surface.MatchedPhaseLabelLine = + TEXT("Requested phase label on execute: unavailable"); + Surface.MatchedPhasePartitionLine = + TEXT("Requested phase partition on execute: unavailable"); + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection merged ordered roster phase-id lookup inspect is active, but no phase id was requested."); + } + else if (OptionMenuSurface.bHasUnresolvedSelectionDetail) + { + Surface.CurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupLine = + OptionMenuSurface.UnresolvedSelectionLine; + Surface.MatchedPhaseOrderLine = + TEXT("Requested phase order on execute: unavailable until the cached selection resolves to an imported option."); + Surface.MatchedPhaseLabelLine = + TEXT("Requested phase label on execute: unavailable until the cached selection resolves to an imported option."); + Surface.MatchedPhasePartitionLine = + TEXT("Requested phase partition on execute: unavailable until the cached selection resolves to an imported option."); + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection merged ordered roster phase-id lookup inspect is active, but the cached selection no longer matches an imported option."); + } + else if (MergedOrderedRosterSurface.bPreviewBlocked) + { + Surface.CurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupLine = + MergedOrderedRosterSurface.CurrentSelectionLabelProvenancePartitionMergedOrderedRosterLine; + Surface.MatchedPhaseOrderLine = + TEXT("Requested phase order on execute: blocked until execute-time merged ordered roster inspection is available."); + Surface.MatchedPhaseLabelLine = + TEXT("Requested phase label on execute: blocked until execute-time merged ordered roster inspection is available."); + Surface.MatchedPhasePartitionLine = + TEXT("Requested phase partition on execute: blocked until execute-time merged ordered roster inspection is available."); + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection merged ordered roster phase-id lookup inspect resolves the active selection, but execute-time phase-id lookup remains blocked."); + } + else if (MergedOrderedRosterSurface.bHasCurrentSelectionLabelProvenancePartitionMergedOrderedRoster) + { + Surface.bLookupMissesRetainedRoster = true; + Surface.CurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupLine = + FString::Printf( + TEXT("Current-selection merged ordered phase-id lookup on execute: phase id %s is not retained in the merged ordered roster."), + *PhaseId + ); + Surface.MatchedPhaseOrderLine = + TEXT("Requested phase order on execute: no retained phase matches that phase id"); + Surface.MatchedPhaseLabelLine = + TEXT("Requested phase label on execute: no retained phase matches that phase id"); + Surface.MatchedPhasePartitionLine = + TEXT("Requested phase partition on execute: no retained phase matches that phase id"); + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection merged ordered roster phase-id lookup inspect resolves the active selection, but the requested phase id is not retained."); + } + else if (MergedOrderedRosterSurface.bHasExactCurrentSelectionLabelProvenancePartitionMergedOrderedRoster) + { + Surface.CurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupLine = + TEXT("Current-selection merged ordered phase-id lookup on execute: none"); + Surface.MatchedPhaseOrderLine = + TEXT("Requested phase order on execute: none"); + Surface.MatchedPhaseLabelLine = + TEXT("Requested phase label on execute: none"); + Surface.MatchedPhasePartitionLine = + TEXT("Requested phase partition on execute: none"); + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection merged ordered roster phase-id lookup inspect resolves the active selection, and no surviving phases are currently retained."); + } + else if (OptionMenuSurface.bHasSelection) + { + Surface.CurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupLine = + TEXT("Current selection has no additional owned-execution split-phase merged ordered roster phase-id lookup preview."); + Surface.MatchedPhaseOrderLine = + TEXT("Requested phase order on execute: unavailable"); + Surface.MatchedPhaseLabelLine = + TEXT("Requested phase label on execute: unavailable"); + Surface.MatchedPhasePartitionLine = + TEXT("Requested phase partition on execute: unavailable"); + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection merged ordered roster phase-id lookup inspect is active, but the current selection does not expose merged ordered roster lookup detail."); + } + else if (OptionMenuSurface.bHasSelector) + { + Surface.CurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupLine = + TEXT("Current selection: unresolved"); + Surface.MatchedPhaseOrderLine = + TEXT("Requested phase order on execute: unresolved"); + Surface.MatchedPhaseLabelLine = + TEXT("Requested phase label on execute: unresolved"); + Surface.MatchedPhasePartitionLine = + TEXT("Requested phase partition on execute: unresolved"); + Surface.StatusLine = + TEXT("Generated-mode selector option owned-execution split-phase current-selection merged ordered roster phase-id lookup inspect is active, but this selector is currently unresolved."); + } + else + { + Surface.CurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupLine = + TEXT("Current selection: n/a"); + Surface.MatchedPhaseOrderLine = + TEXT("Requested phase order on execute: n/a"); + Surface.MatchedPhaseLabelLine = + TEXT("Requested phase label on execute: n/a"); + Surface.MatchedPhasePartitionLine = + TEXT("Requested phase partition on execute: n/a"); + Surface.StatusLine = MergedOrderedRosterSurface.StatusLine; + } + + Surface.DetailLine = FString::Printf( + TEXT("%s | %s | %s"), + *Surface.CurrentSelectionSelectionLine, + *Surface.CurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupLine, + *Surface.MatchedPhasePartitionLine + ); + + return Surface; +} + FHyperTwistTrainingCoachQueueControlSurface UHyperTwistTrainingCoachLibrary::DeriveCoachQueueControlSurface( const FHyperTwistTrainingCoachSessionQueueState& QueueState, diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp index 255ea1d..125ba52 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp @@ -1309,6 +1309,27 @@ UHyperTwistTrainingPanelWidget::GetDisplayedCoachGeneratedModeSelectorOptionOwne ); } +FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface +UHyperTwistTrainingPanelWidget::GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface( + const FString& SelectorId, + const FString& PhaseId +) const +{ + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface OptionMenuSurface = + GetDisplayedCoachGeneratedModeSelectorOptionMenuSurface(SelectorId); + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface + OptionLaunchRequestPreviewSurface = + GetDisplayedCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface(SelectorId); + return UHyperTwistTrainingCoachLibrary:: + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface( + CachedRunState, + SelectorId, + PhaseId, + OptionMenuSurface, + OptionLaunchRequestPreviewSurface + ); +} + FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartCoachRecommendedRun( const int32 MaxCases, const FString& StartActionSourceLabel diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp index 9a84daf..0864e1a 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp @@ -1290,6 +1290,27 @@ AHyperTwistTrainingSessionActor::GetDisplayedCoachGeneratedModeSelectorOptionOwn ); } +FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface +AHyperTwistTrainingSessionActor::GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface( + const FString& SelectorId, + const FString& PhaseId +) const +{ + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface OptionMenuSurface = + GetDisplayedCoachGeneratedModeSelectorOptionMenuSurface(SelectorId); + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface + OptionLaunchRequestPreviewSurface = + GetDisplayedCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface(SelectorId); + return UHyperTwistTrainingCoachLibrary:: + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface( + CachedRunState, + SelectorId, + PhaseId, + OptionMenuSurface, + OptionLaunchRequestPreviewSurface + ); +} + FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartCoachRecommendedTrainingRun( const int32 MaxCases ) diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h index 1e456c4..8ac9f25 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h @@ -1007,4 +1007,15 @@ public: const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface& OptionLaunchRequestPreviewSurface ); + + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach") + static FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface + DeriveCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface( + const FHyperTwistTrainingRunState& RunState, + const FString& SelectorId, + const FString& PhaseId, + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface& OptionMenuSurface, + const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface& + OptionLaunchRequestPreviewSurface + ); }; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h index cbdcf69..20f2774 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h @@ -434,6 +434,13 @@ public: const FString& SelectorId ) const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach") + FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface + GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface( + const FString& SelectorId, + const FString& PhaseId + ) const; + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach") FHyperTwistTrainingRunState StartCoachRecommendedRun( int32 MaxCases, diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h index a5b640e..5180811 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h @@ -415,6 +415,13 @@ public: const FString& SelectorId ) const; + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach") + FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface + GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface( + const FString& SelectorId, + const FString& PhaseId + ) const; + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach") FHyperTwistTrainingRunState StartCoachRecommendedTrainingRun(int32 MaxCases); diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h index 4eec586..d46fba1 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h @@ -14517,3 +14517,118 @@ struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPha || bHasCurrentSelectionLabelProvenancePartitionMergedOrderedRoster; } }; + +USTRUCT(BlueprintType) +struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupInspectSurface +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SelectorId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SelectorLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString BindingLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Headline; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString StatusLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionSelectionLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString LookupPhaseId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString MergedOrderedPhaseCountLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString MatchedPhaseOrderLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString MatchedPhaseLabelLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString MatchedPhasePartitionLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DetailLine; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionSplitPhaseCurrentSelectionLabelProvenancePartitionMergedOrderedRosterInspectPhaseSurface + MatchedPhase; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionOptionId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionOptionLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CurrentSelectionOptionValue; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind LaunchRequestPreviewKind = + EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 MatchedNormalizedOrder = -1; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasSelector = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasSelection = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bSelectionMatchesAvailableOption = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasLookupPhaseId = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookup = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bStartsOwnedCaseImmediately = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasExactCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookup = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bRetainsActiveDeckSplitPhaseFusion = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bMatchedExplicitLabelPartition = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bMatchedFallbackLabelPartition = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bLookupMissesRetainedRoster = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bPreviewBlocked = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bCanPreview = false; + + bool IsStructurallyValid() const + { + return !StatusLine.IsEmpty() + || !SelectorId.IsEmpty() + || !CurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookupLine.IsEmpty() + || MatchedPhase.IsStructurallyValid() + || bHasSelector + || bHasSelection + || bHasCurrentSelectionLabelProvenancePartitionMergedOrderedRosterPhaseIdLookup; + } +}; diff --git a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md index cd4265e..6d8bf2b 100644 --- a/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md +++ b/docs/HYPERTWIST_ROADMAP_OVERHAUL_EXPANSION_GUIDE.md @@ -68,8 +68,8 @@ Current correction call from the source-exposed audit and current execution refr - the imported generated-mode gap is closed; request/config/selection plumbing and the bounded clean-room executor are already landed in first-party code - the latest landed bounded `Phase 4` packet closes the retained-idle comparison/outcome actionability gap at the end of the recognition-assisted coach-to-review continuity lane, and the final retained-surface confirmation pass now leaves that closure lane functionally complete - the retained idle widget surface now keeps retained comparison and decision history inspectable without continuing to advertise live launch or guidance-outcome actions once the coach-to-review loop has already collapsed to truthful closed-loop idle - - the latest landed bounded `Phase 4` packet stays on that same gameplay-facing consumer lane and adds one thin generated-mode selector option owned execution split-phase current-selection label-provenance partition merged ordered roster inspect surface over the already-cached selector/runtime/request state, so gameplay/Blueprint callers can inspect the active selection's retained split phases in one ordered list with explicit-label vs phase-id-fallback partition tagging instead of stitching the paired detail arrays together themselves - - the current next bounded packet is to expose one thin generated-mode selector option owned execution split-phase current-selection label-provenance partition merged ordered roster phase-id lookup inspect surface on those same two consumer surfaces so gameplay/Blueprint callers can inspect one retained split-phase row by phase id without scanning the merged ordered roster array themselves + - the latest landed bounded `Phase 4` packet stays on that same gameplay-facing consumer lane and adds one thin generated-mode selector option owned execution split-phase current-selection label-provenance partition merged ordered roster phase-id lookup inspect surface over the already-cached selector/runtime/request state, so gameplay/Blueprint callers can inspect one retained split-phase row by phase id without scanning the merged ordered roster array themselves + - the current next bounded packet is to expose one thin generated-mode selector option owned execution split-phase current-selection label-provenance partition merged ordered roster normalized-order lookup inspect surface on those same two consumer surfaces so gameplay/Blueprint callers can inspect one retained split-phase row by normalized execution order without scanning the merged ordered roster array themselves - the current execution-discipline rule that broad refactor / monolith-splitting work should not interrupt the active bounded roadmap packet unless structure is actually blocking it ## Current execution-reality references diff --git a/docs/arch/HYPERTWIST_PHASE4_GAMEPLAY_GENERATED_MODE_SELECTOR_OPTION_OWNED_EXECUTION_SPLIT_PHASE_CURRENT_SELECTION_LABEL_PROVENANCE_PARTITION_MERGED_ORDERED_ROSTER_PHASE_ID_LOOKUP_INSPECT_SURFACE_PACKET_2026-05-09.md b/docs/arch/HYPERTWIST_PHASE4_GAMEPLAY_GENERATED_MODE_SELECTOR_OPTION_OWNED_EXECUTION_SPLIT_PHASE_CURRENT_SELECTION_LABEL_PROVENANCE_PARTITION_MERGED_ORDERED_ROSTER_PHASE_ID_LOOKUP_INSPECT_SURFACE_PACKET_2026-05-09.md new file mode 100644 index 0000000..e61b9dd --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASE4_GAMEPLAY_GENERATED_MODE_SELECTOR_OPTION_OWNED_EXECUTION_SPLIT_PHASE_CURRENT_SELECTION_LABEL_PROVENANCE_PARTITION_MERGED_ORDERED_ROSTER_PHASE_ID_LOOKUP_INSPECT_SURFACE_PACKET_2026-05-09.md @@ -0,0 +1,33 @@ +# HyperTwist Phase 4 gameplay generated-mode selector option owned execution split-phase current-selection label-provenance partition merged ordered roster phase-id lookup inspect surface packet + +## Goal + +Close the next thin gameplay-facing consumer seam above the current-selection label-provenance partition merged ordered roster inspect surface by exposing one current-selection merged ordered roster phase-id lookup inspect surface for a chosen selector id and phase id. + +## Why this packet exists + +The current-selection label-provenance partition merged ordered roster inspect surface already exposed the active selection's retained split phases in one ordered list with explicit-label versus phase-id-fallback partition tagging. Gameplay and Blueprint callers that needed one specific retained phase row still had to scan that merged ordered roster array themselves to find a matching phase id and then preserve truthful blocked, unresolved, or missing-row posture. + +This packet removes that caller-side lookup step. It exposes one thin current-selection merged ordered roster phase-id lookup inspect surface that composes the already-landed merged ordered roster inspect surface and returns the matched retained phase row when one exists, while preserving truthful no-request, unresolved-selection, blocked-preview, no-retained-phase, and retained-roster-miss posture. + +## What changed + +- add a first-party owned execution split-phase current-selection merged ordered roster phase-id lookup inspect surface in shared training types +- derive that surface in the coach library by composing the already-landed current-selection merged ordered roster inspect surface instead of reimplementing merged-roster construction logic +- expose the current-selection merged ordered roster phase-id lookup inspect surface on both gameplay-facing consumers: + - `UHyperTwistTrainingPanelWidget` + - `AHyperTwistTrainingSessionActor` +- preserve exact matched retained phase row detail when the requested phase id is present in the active selection's merged ordered retained-phase roster +- preserve truthful lookup-miss, unresolved cached-selection, and blocked-preview posture when a matching retained phase row cannot yet be exposed + +## Validation + +- full `Development Editor|Win64` solution build for `C:\HyperTwist\UnrealHyperTwist\UnrealHyperTwist.sln` + +## Result + +Gameplay and Blueprint callers can now inspect one retained split-phase row for the active selection by phase id without scanning the merged ordered roster array themselves. + +## Next bounded slice + +Stay on the same gameplay-facing consumer lane and expose one thin generated-mode selector option owned execution split-phase current-selection label-provenance partition merged ordered roster normalized-order lookup inspect surface so callers can inspect one retained split-phase row by normalized execution order without scanning the merged ordered roster array themselves.