Expose gameplay selector deck capability preview surface

This commit is contained in:
axiomlogicnexus 2026-05-08 19:01:18 +02:00
parent 0b63bba137
commit 51f6926ab9
9 changed files with 759 additions and 2 deletions

View file

@ -7762,6 +7762,412 @@ UHyperTwistTrainingCoachLibrary::
return Surface;
}
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface
UHyperTwistTrainingCoachLibrary::
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface(
const FHyperTwistTrainingRunState& RunState,
const FString& SelectorId,
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface& OptionMenuSurface,
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface&
OptionLaunchRequestPreviewSurface
)
{
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface
Surface;
Surface.SelectorId = SelectorId;
Surface.SelectorLabel = OptionMenuSurface.SelectorLabel;
Surface.BindingLabel = OptionMenuSurface.BindingLabel;
Surface.Headline =
TEXT("Generated Mode Selector Option Owned-Execution Deck Capability Retention Preview");
Surface.bHasSelector = OptionMenuSurface.bHasSelector;
if (!SelectorId.IsEmpty())
{
Surface.Headline = OptionMenuSurface.SelectorLabel.IsEmpty()
? FString::Printf(
TEXT("Generated Mode Selector Option Owned-Execution Deck Capability Retention Preview: %s"),
*SelectorId
)
: FString::Printf(
TEXT("Generated Mode Selector Option Owned-Execution Deck Capability Retention Preview: %s"),
*OptionMenuSurface.SelectorLabel
);
}
if (SelectorId.IsEmpty())
{
Surface.StatusLine =
TEXT("Generated-mode selector option owned-execution deck capability retention preview requires a selector id from the active selector roster.");
Surface.RealScrambleSummaryLine = TEXT("Real scrambles: n/a");
Surface.VirtualCubeSummaryLine = TEXT("Virtual cube: n/a");
Surface.SmartCubeSummaryLine = TEXT("Smart cube: n/a");
Surface.CurrentSelectionCapabilityLine = TEXT("Current selection: n/a");
Surface.DetailLine = OptionLaunchRequestPreviewSurface.StatusLine.IsEmpty()
? TEXT("Launch-request preview: n/a")
: FString::Printf(
TEXT("Launch-request preview: %s"),
*OptionLaunchRequestPreviewSurface.StatusLine
);
return Surface;
}
const FHyperTwistTrainingImportedRuntimeSurface& RuntimeSurface =
RunState.ActiveDeck.ImportedRuntimeSurface;
const bool bHasGeneratedModeSurface = RuntimeSurface.IsStructurallyValid()
&& RuntimeSurface.SurfaceKind.Equals(TEXT("generated-mode"), ESearchCase::IgnoreCase);
const auto BuildCapabilityLine = [](
const TCHAR* Prefix,
const bool bEnabled,
const TCHAR* EnabledText,
const TCHAR* DisabledText
) -> FString
{
return FString::Printf(
TEXT("%s: %s"),
Prefix,
bEnabled ? EnabledText : DisabledText
);
};
const auto IncrementCapabilityCounts = [&Surface](
const bool bUsesRealScrambles,
const bool bSupportsVirtualCube,
const bool bSupportsSmartCube
)
{
if (bUsesRealScrambles)
{
++Surface.RealScrambleEnabledOptionCount;
}
else
{
++Surface.RealScrambleDisabledOptionCount;
}
if (bSupportsVirtualCube)
{
++Surface.VirtualCubeEnabledOptionCount;
}
else
{
++Surface.VirtualCubeDisabledOptionCount;
}
if (bSupportsSmartCube)
{
++Surface.SmartCubeEnabledOptionCount;
}
else
{
++Surface.SmartCubeDisabledOptionCount;
}
};
if (!RunState.IsStructurallyValid() || !bHasGeneratedModeSurface)
{
Surface.StatusLine = OptionMenuSurface.StatusLine.IsEmpty()
? TEXT("Generated-mode selector option owned-execution deck capability retention preview is not currently available.")
: OptionMenuSurface.StatusLine;
Surface.RealScrambleSummaryLine = TEXT("Real scrambles: n/a");
Surface.VirtualCubeSummaryLine = TEXT("Virtual cube: n/a");
Surface.SmartCubeSummaryLine = TEXT("Smart cube: n/a");
Surface.CurrentSelectionCapabilityLine = OptionMenuSurface.bHasUnresolvedSelectionDetail
? OptionMenuSurface.UnresolvedSelectionLine
: (OptionMenuSurface.bHasSelection
? TEXT("Current selection remains cached, but no active owned-execution deck capability preview is available.")
: TEXT("Current selection: unresolved"));
Surface.DetailLine = FString::Printf(
TEXT("Launch-request preview: %s"),
OptionLaunchRequestPreviewSurface.StatusLine.IsEmpty()
? TEXT("n/a")
: *OptionLaunchRequestPreviewSurface.StatusLine
);
return Surface;
}
for (const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewEntrySurface&
PreviewEntry : OptionLaunchRequestPreviewSurface.OptionEntries)
{
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewEntrySurface
Entry;
Entry.OptionId = PreviewEntry.OptionId;
Entry.Label = PreviewEntry.Label;
Entry.OptionValue = PreviewEntry.OptionValue;
Entry.LaunchRequestPreviewKind = PreviewEntry.LaunchRequestPreviewKind;
Entry.bMatchesCurrentSelection = PreviewEntry.bMatchesCurrentSelection;
Entry.bStartsOwnedCaseImmediately = PreviewEntry.bStartsOwnedCaseImmediately;
switch (PreviewEntry.LaunchRequestPreviewKind)
{
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
DirectOwnedCaseStart:
Entry.bPreviewUsesRealScrambles = RunState.ActiveDeck.bUsesRealScrambles;
Entry.bPreviewSupportsVirtualCube = RunState.ActiveDeck.bSupportsVirtualCube;
Entry.bPreviewSupportsSmartCube = RunState.ActiveDeck.bSupportsSmartCube;
Entry.RealScrambleLine = BuildCapabilityLine(
TEXT("Real-scramble posture on execute"),
Entry.bPreviewUsesRealScrambles,
TEXT("enabled"),
TEXT("disabled")
);
Entry.VirtualCubeLine = BuildCapabilityLine(
TEXT("Virtual-cube posture on execute"),
Entry.bPreviewSupportsVirtualCube,
TEXT("enabled"),
TEXT("disabled")
);
Entry.SmartCubeLine = BuildCapabilityLine(
TEXT("Smart-cube posture on execute"),
Entry.bPreviewSupportsSmartCube,
TEXT("enabled"),
TEXT("disabled")
);
Entry.CapabilitySourceLine =
TEXT("Capability source: exact active deck capability flags retained on direct covered-case start.");
Entry.PreviewStabilityLine =
TEXT("Preview stability: exact direct owned-execution deck capability posture from covered-case launch.");
Entry.bHasExactCapabilityPreview = true;
Entry.bRetainsActiveDeckCapabilityFlags = true;
Entry.bCanPreview = true;
++Surface.DirectExactOptionCount;
++Surface.RetainedActiveDeckCapabilityOptionCount;
IncrementCapabilityCounts(
Entry.bPreviewUsesRealScrambles,
Entry.bPreviewSupportsVirtualCube,
Entry.bPreviewSupportsSmartCube
);
break;
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
StoredRequestReusable:
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
RefreshRequired:
Entry.bPreviewUsesRealScrambles = RunState.ActiveDeck.bUsesRealScrambles;
Entry.bPreviewSupportsVirtualCube = RunState.ActiveDeck.bSupportsVirtualCube;
Entry.bPreviewSupportsSmartCube = RunState.ActiveDeck.bSupportsSmartCube;
Entry.RealScrambleLine = BuildCapabilityLine(
TEXT("Real-scramble posture on execute"),
Entry.bPreviewUsesRealScrambles,
TEXT("enabled"),
TEXT("disabled")
);
Entry.VirtualCubeLine = BuildCapabilityLine(
TEXT("Virtual-cube posture on execute"),
Entry.bPreviewSupportsVirtualCube,
TEXT("enabled"),
TEXT("disabled")
);
Entry.SmartCubeLine = BuildCapabilityLine(
TEXT("Smart-cube posture on execute"),
Entry.bPreviewSupportsSmartCube,
TEXT("enabled"),
TEXT("disabled")
);
Entry.CapabilitySourceLine =
TEXT("Capability source: exact source deck capability flags retained on generated owned execution.");
Entry.PreviewStabilityLine =
PreviewEntry.LaunchRequestPreviewKind
== EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
StoredRequestReusable
? TEXT("Preview stability: exact while execute reuses the current stored request.")
: TEXT("Preview stability: exact even though execute still needs launch-request refresh.");
Entry.bHasExactCapabilityPreview = true;
Entry.bRetainsActiveDeckCapabilityFlags = true;
Entry.bCanPreview = true;
++Surface.GeneratedExactOptionCount;
++Surface.RetainedActiveDeckCapabilityOptionCount;
IncrementCapabilityCounts(
Entry.bPreviewUsesRealScrambles,
Entry.bPreviewSupportsVirtualCube,
Entry.bPreviewSupportsSmartCube
);
break;
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
UnresolvedAfterChoice:
Entry.RealScrambleLine =
TEXT("Real-scramble posture on execute: blocked until every required selector is resolved.");
Entry.VirtualCubeLine =
TEXT("Virtual-cube posture on execute: blocked until every required selector is resolved.");
Entry.SmartCubeLine =
TEXT("Smart-cube posture on execute: blocked until every required selector is resolved.");
Entry.CapabilitySourceLine =
TEXT("Capability source: blocked while selector coverage remains incomplete.");
Entry.PreviewStabilityLine =
TEXT("Preview stability: blocked while selector coverage remains incomplete.");
Entry.bPreviewBlocked = true;
Entry.bCanPreview = true;
++Surface.BlockedOptionCount;
break;
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::
PayloadUnavailable:
Entry.RealScrambleLine =
TEXT("Real-scramble posture on execute: blocked until a structurally valid launch payload can be derived.");
Entry.VirtualCubeLine =
TEXT("Virtual-cube posture on execute: blocked until a structurally valid launch payload can be derived.");
Entry.SmartCubeLine =
TEXT("Smart-cube posture on execute: blocked until a structurally valid launch payload can be derived.");
Entry.CapabilitySourceLine =
TEXT("Capability source: blocked while the hypothetical generated-mode payload remains structurally invalid.");
Entry.PreviewStabilityLine =
TEXT("Preview stability: blocked while the hypothetical generated-mode payload remains structurally invalid.");
Entry.bPreviewBlocked = true;
Entry.bCanPreview = true;
++Surface.BlockedOptionCount;
break;
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::Unavailable:
case EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::None:
default:
Entry.RealScrambleLine = TEXT("Real-scramble posture on execute: unavailable");
Entry.VirtualCubeLine = TEXT("Virtual-cube posture on execute: unavailable");
Entry.SmartCubeLine = TEXT("Smart-cube posture on execute: unavailable");
Entry.CapabilitySourceLine = TEXT("Capability source: unavailable");
Entry.PreviewStabilityLine = TEXT("Preview stability: unavailable");
Entry.bCanPreview = false;
++Surface.UnavailableOptionCount;
break;
}
const FString EntryDetail = Entry.CapabilitySourceLine.IsEmpty()
? Entry.PreviewStabilityLine
: FString::Printf(
TEXT("%s | %s"),
*Entry.PreviewStabilityLine,
*Entry.CapabilitySourceLine
);
Entry.DetailLine = PreviewEntry.DetailLine.IsEmpty()
? EntryDetail
: FString::Printf(TEXT("%s | %s"), *EntryDetail, *PreviewEntry.DetailLine);
if (Entry.bMatchesCurrentSelection)
{
Surface.bCurrentSelectionHasExactCapabilityPreview =
Entry.bHasExactCapabilityPreview;
Surface.bCurrentSelectionUsesRealScrambles =
Entry.bPreviewUsesRealScrambles;
Surface.bCurrentSelectionSupportsVirtualCube =
Entry.bPreviewSupportsVirtualCube;
Surface.bCurrentSelectionSupportsSmartCube =
Entry.bPreviewSupportsSmartCube;
Surface.bCurrentSelectionRetainsActiveDeckCapabilityFlags =
Entry.bRetainsActiveDeckCapabilityFlags;
Surface.CurrentSelectionCapabilityLine = FString::Printf(
TEXT("%s | %s | %s"),
*Entry.RealScrambleLine,
*Entry.VirtualCubeLine,
*Entry.SmartCubeLine
);
}
Surface.OptionEntries.Add(MoveTemp(Entry));
}
Surface.bHasOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewOptions =
Surface.OptionEntries.Num() > 0;
Surface.bHasDirectRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewOptions =
Surface.DirectExactOptionCount > 0;
Surface.bHasGeneratedRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewOptions =
Surface.GeneratedExactOptionCount > 0;
Surface.bHasBlockedRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewOptions =
Surface.BlockedOptionCount > 0;
Surface.RealScrambleSummaryLine = Surface.OptionEntries.Num() > 0
? FString::Printf(
TEXT("Real scrambles: %d enabled | %d disabled | %d blocked | %d unavailable"),
Surface.RealScrambleEnabledOptionCount,
Surface.RealScrambleDisabledOptionCount,
Surface.BlockedOptionCount,
Surface.UnavailableOptionCount
)
: TEXT("Real scrambles: no imported options");
Surface.VirtualCubeSummaryLine = Surface.OptionEntries.Num() > 0
? FString::Printf(
TEXT("Virtual cube: %d enabled | %d disabled | %d blocked | %d unavailable"),
Surface.VirtualCubeEnabledOptionCount,
Surface.VirtualCubeDisabledOptionCount,
Surface.BlockedOptionCount,
Surface.UnavailableOptionCount
)
: TEXT("Virtual cube: no imported options");
Surface.SmartCubeSummaryLine = Surface.OptionEntries.Num() > 0
? FString::Printf(
TEXT("Smart cube: %d enabled | %d disabled | %d blocked | %d unavailable"),
Surface.SmartCubeEnabledOptionCount,
Surface.SmartCubeDisabledOptionCount,
Surface.BlockedOptionCount,
Surface.UnavailableOptionCount
)
: TEXT("Smart cube: no imported options");
if (Surface.CurrentSelectionCapabilityLine.IsEmpty())
{
if (OptionMenuSurface.bHasUnresolvedSelectionDetail)
{
Surface.CurrentSelectionCapabilityLine =
OptionMenuSurface.UnresolvedSelectionLine;
}
else if (OptionMenuSurface.bHasSelection)
{
Surface.CurrentSelectionCapabilityLine =
TEXT("Current selection has no additional owned-execution deck capability preview.");
}
else if (OptionMenuSurface.bHasSelector)
{
Surface.CurrentSelectionCapabilityLine = TEXT("Current selection: unresolved");
}
else
{
Surface.CurrentSelectionCapabilityLine = TEXT("Current selection: n/a");
}
}
if (OptionMenuSurface.bHasSelector && Surface.OptionEntries.Num() > 0)
{
Surface.StatusLine = FString::Printf(
TEXT("Generated-mode selector option owned-execution deck capability retention preview exposes %d direct exact option%s, %d generated exact option%s, %d blocked option%s, and %d unavailable option%s."),
Surface.DirectExactOptionCount,
Surface.DirectExactOptionCount == 1 ? TEXT("") : TEXT("s"),
Surface.GeneratedExactOptionCount,
Surface.GeneratedExactOptionCount == 1 ? TEXT("") : TEXT("s"),
Surface.BlockedOptionCount,
Surface.BlockedOptionCount == 1 ? TEXT("") : TEXT("s"),
Surface.UnavailableOptionCount,
Surface.UnavailableOptionCount == 1 ? TEXT("") : TEXT("s")
);
}
else if (OptionMenuSurface.bHasSelector)
{
Surface.StatusLine =
TEXT("Generated-mode selector option owned-execution deck capability retention preview is active, but this selector does not expose imported options.");
}
else
{
Surface.StatusLine = OptionMenuSurface.StatusLine.IsEmpty()
? TEXT("Generated-mode selector option owned-execution deck capability retention preview is not currently available.")
: OptionMenuSurface.StatusLine;
}
const FString SelectorSummary = Surface.SelectorLabel.IsEmpty()
? (Surface.SelectorId.IsEmpty() ? FString(TEXT("n/a")) : Surface.SelectorId)
: Surface.SelectorLabel;
const FString BindingSummary = Surface.BindingLabel.IsEmpty()
? FString(TEXT("n/a"))
: Surface.BindingLabel;
Surface.DetailLine = FString::Printf(
TEXT("Launch-request preview: %s | Selector: %s | Binding: %s"),
OptionLaunchRequestPreviewSurface.StatusLine.IsEmpty()
? TEXT("n/a")
: *OptionLaunchRequestPreviewSurface.StatusLine,
*SelectorSummary,
*BindingSummary
);
return Surface;
}
FHyperTwistTrainingCoachQueueControlSurface
UHyperTwistTrainingCoachLibrary::DeriveCoachQueueControlSurface(
const FHyperTwistTrainingCoachSessionQueueState& QueueState,

View file

@ -1024,6 +1024,25 @@ UHyperTwistTrainingPanelWidget::GetDisplayedCoachGeneratedModeSelectorOptionOwne
);
}
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface
UHyperTwistTrainingPanelWidget::GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface(
const FString& SelectorId
) const
{
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface OptionMenuSurface =
GetDisplayedCoachGeneratedModeSelectorOptionMenuSurface(SelectorId);
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface
OptionLaunchRequestPreviewSurface =
GetDisplayedCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface(SelectorId);
return UHyperTwistTrainingCoachLibrary::
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface(
CachedRunState,
SelectorId,
OptionMenuSurface,
OptionLaunchRequestPreviewSurface
);
}
FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartCoachRecommendedRun(
const int32 MaxCases,
const FString& StartActionSourceLabel

View file

@ -1005,6 +1005,25 @@ AHyperTwistTrainingSessionActor::GetDisplayedCoachGeneratedModeSelectorOptionOwn
);
}
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface
AHyperTwistTrainingSessionActor::GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface(
const FString& SelectorId
) const
{
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface OptionMenuSurface =
GetDisplayedCoachGeneratedModeSelectorOptionMenuSurface(SelectorId);
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface
OptionLaunchRequestPreviewSurface =
GetDisplayedCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface(SelectorId);
return UHyperTwistTrainingCoachLibrary::
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface(
CachedRunState,
SelectorId,
OptionMenuSurface,
OptionLaunchRequestPreviewSurface
);
}
FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartCoachRecommendedTrainingRun(
const int32 MaxCases
)

View file

@ -857,4 +857,14 @@ public:
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface&
OptionLaunchRequestPreviewSurface
);
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
static FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface
DeriveCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface(
const FHyperTwistTrainingRunState& RunState,
const FString& SelectorId,
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionMenuSurface& OptionMenuSurface,
const FHyperTwistTrainingCoachGeneratedModeSelectorOptionLaunchRequestPreviewSurface&
OptionLaunchRequestPreviewSurface
);
};

View file

@ -344,6 +344,12 @@ public:
const FString& SelectorId
) const;
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface
GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface(
const FString& SelectorId
) const;
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
FHyperTwistTrainingRunState StartCoachRecommendedRun(
int32 MaxCases,

View file

@ -325,6 +325,12 @@ public:
const FString& SelectorId
) const;
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface
GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface(
const FString& SelectorId
) const;
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
FHyperTwistTrainingRunState StartCoachRecommendedTrainingRun(int32 MaxCases);

View file

@ -11711,3 +11711,191 @@ struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionDelivery
|| bHasOwnedExecutionDeliveryModeRosterAllowedModeRetentionPreviewOptions;
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewEntrySurface
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString OptionId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString Label;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString OptionValue;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind LaunchRequestPreviewKind =
EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::None;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString RealScrambleLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString VirtualCubeLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString SmartCubeLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString CapabilitySourceLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString PreviewStabilityLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString DetailLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bPreviewUsesRealScrambles = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bPreviewSupportsVirtualCube = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bPreviewSupportsSmartCube = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bMatchesCurrentSelection = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bStartsOwnedCaseImmediately = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bHasExactCapabilityPreview = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bRetainsActiveDeckCapabilityFlags = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bPreviewBlocked = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bCanPreview = false;
bool IsStructurallyValid() const
{
return !OptionId.IsEmpty()
|| !Label.IsEmpty()
|| !RealScrambleLine.IsEmpty()
|| !VirtualCubeLine.IsEmpty()
|| !SmartCubeLine.IsEmpty()
|| LaunchRequestPreviewKind
!= EHyperTwistTrainingCoachGeneratedModeOptionLaunchRequestPreviewKind::None
|| bCanPreview;
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface
{
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 RealScrambleSummaryLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString VirtualCubeSummaryLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString SmartCubeSummaryLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString CurrentSelectionCapabilityLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString DetailLine;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
TArray<FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewEntrySurface>
OptionEntries;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 DirectExactOptionCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 GeneratedExactOptionCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 BlockedOptionCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 UnavailableOptionCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 RealScrambleEnabledOptionCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 RealScrambleDisabledOptionCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 VirtualCubeEnabledOptionCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 VirtualCubeDisabledOptionCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 SmartCubeEnabledOptionCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 SmartCubeDisabledOptionCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 RetainedActiveDeckCapabilityOptionCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bHasSelector = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bHasOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewOptions = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bHasDirectRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewOptions = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bHasGeneratedRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewOptions = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bHasBlockedRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewOptions = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bCurrentSelectionHasExactCapabilityPreview = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bCurrentSelectionUsesRealScrambles = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bCurrentSelectionSupportsVirtualCube = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bCurrentSelectionSupportsSmartCube = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
bool bCurrentSelectionRetainsActiveDeckCapabilityFlags = false;
bool IsStructurallyValid() const
{
return !StatusLine.IsEmpty()
|| !SelectorId.IsEmpty()
|| OptionEntries.Num() > 0
|| bHasSelector
|| bHasOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewOptions;
}
};

View file

@ -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 delivery-mode roster / allowed-mode retention preview surface over the already-cached selector/runtime/request state, so gameplay/Blueprint callers can render retained execution-modality posture for a chosen option without rebuilding generated deck composition rules directly
- the current next bounded packet is to expose one thin generated-mode selector option owned execution real-scramble / virtual-cube / smart-cube capability retention preview surface on those same two consumer surfaces so gameplay/Blueprint callers can render retained deck capability posture for a chosen option without rebuilding generated deck composition rules directly
- 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 real-scramble / virtual-cube / smart-cube capability retention preview surface over the already-cached selector/runtime/request state, so gameplay/Blueprint callers can render retained deck capability posture for a chosen option without rebuilding generated deck composition rules directly
- the current next bounded packet is to expose one thin generated-mode selector option owned execution timing-policy retention preview surface on those same two consumer surfaces so gameplay/Blueprint callers can render inspection and run-timing posture for a chosen option without rebuilding generated deck composition rules directly
- 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

View file

@ -0,0 +1,103 @@
# HyperTwist Phase 4 gameplay generated-mode selector option owned execution real-scramble / virtual-cube / smart-cube capability retention preview surface packet
Created on `2026-05-08`
Status:
- first-party HyperTwist packet
- bounded Phase `4` gameplay-facing consumer slice
## Purpose
This packet closes the next thin gameplay-facing consumer seam above the panel-widget and session-actor generated-mode selector option owned execution delivery-mode roster / allowed-mode retention preview surface by exposing one parameterized owned execution real-scramble / virtual-cube / smart-cube capability retention preview surface for a chosen selector id.
The open tasks were:
- stop forcing gameplay / Blueprint callers to rebuild retained deck capability flags just to explain whether a chosen imported option would keep real scrambles, virtual-cube support, and smart-cube support on execute
- expose direct covered-case capability retention and generated owned-execution capability retention on the same thin consumer lane
- expose resulting retained deck capability posture without widening into backend execution behavior
It is not:
- a selector-dispatch behavior change
- a generated-mode launch-request persistence behavior change
- a generated-mode execution deck synthesis change
- a broader gameplay UI composition pass
## Scope
Bounded lane:
- add first-party owned execution capability-retention preview surfaces in shared training types
- add a coach-library helper that projects retained deck capability flags over the already-landed launch-request preview surface and active run state
- expose that parameterized capability-retention preview surface on `HyperTwistTrainingPanelWidget` and `HyperTwistTrainingSessionActor`
- keep the derivation presentation-only and rooted in the already-owned selector/runtime/request surfaces
Out of scope:
- changing selector-choice apply behavior
- changing stored launch-request creation, refresh, or execute behavior
- changing generated-mode execution deck synthesis
- widening into dashboard-only or broader gameplay composition work
## Why this was the right next packet
Before this slice:
- gameplay-facing panel/session consumers already exposed truthful owned case identity, prompt presentation, execution modality, execution scope, provenance posture, deck container posture, retained runtime-surface identity, and retained delivery-mode posture for imported selector options
- callers could tell what owned execution would run, what container/runtime identity it would keep, and what delivery-mode posture it would retain
But one thin consumer seam was still open:
- callers still had to reconstruct retained deck capability flags from direct covered-case behavior and generated owned-execution deck synthesis rules if they wanted to explain whether a chosen option would keep real scrambles, virtual-cube support, or smart-cube support
That meant:
- single execution-mode and roster-level modality preview were already thin and reusable
- but retained deck capability posture still leaked generated deck composition rules into callers
So the next bounded move was:
- keep the already-landed owned execution delivery-mode roster / allowed-mode retention preview surface unchanged in behavior
- reuse the already-cached launch-request preview surface and active run state to expose one narrow retained deck capability preview surface above it
## What landed
Primary code changes:
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h`
- added `FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewEntrySurface`
- added `FHyperTwistTrainingCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface`
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h`
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp`
- added `DeriveCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface(...)`
- capability-retention preview is derived from cached run state plus the already-landed launch-request preview surface
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h`
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp`
- added `GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface(const FString& SelectorId)`
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h`
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp`
- added `GetDisplayedCoachGeneratedModeSelectorOptionOwnedExecutionRealScrambleVirtualCubeSmartCubeCapabilityRetentionPreviewSurface(const FString& SelectorId)`
Surface behavior:
- reports exact retained active-deck capability flags for direct covered-case starts
- reports exact retained source-deck capability flags for generated owned-execution paths
- stays intentionally scoped to `bUsesRealScrambles`, `bSupportsVirtualCube`, and `bSupportsSmartCube`, because reveal posture already has its own owned-execution preview surface and generated owned execution adjusts reveal separately
- keeps reusable stored-request cases and refresh-required generated cases exact because those three retained capability flags do not depend on the eventual request id
- keeps unresolved or payload-invalid choices inspectable as blocked capability preview states instead of collapsing them into a generic unavailable branch
- keeps the surface presentation-only and compatible with the already-landed launch / execution, request-alignment, stored-request delta, launch-request payload / refresh-preview, launch-request metadata / origin-notes preview, launch-request envelope / request-source preview, owned execution case / canonical-state preview, owned execution prompt preview, owned execution delivery preview, owned execution scope preview, owned execution provenance preview, owned execution deck-title / selection-policy preview, owned execution deck-id / runtime-surface retention preview, and owned execution delivery-mode roster / allowed-mode retention preview surfaces
## Validation
Validation target:
- full `Development Editor|Win64` build of `C:\HyperTwist\UnrealHyperTwist\UnrealHyperTwist.sln`
Result:
- passed with `0` warnings and `0` errors
## Follow-on
The next bounded packet on this same gameplay-facing consumer lane should stay thin and expose one generated-mode selector option owned execution timing-policy retention preview surface so callers can render inspection and run-timing posture for a chosen option without rebuilding generated deck composition rules directly.