Expose gameplay focus provenance surface
This commit is contained in:
parent
0d813df46b
commit
53bb7ab349
9 changed files with 474 additions and 2 deletions
|
|
@ -3,6 +3,7 @@
|
|||
namespace HyperTwistTrainingCoachLibraryInternal
|
||||
{
|
||||
EHyperTwistCoachPriority PriorityFromScore(const float Score);
|
||||
FString DescribeCoachMemorySourceLabel(const FString& SourceLabel);
|
||||
|
||||
EHyperTwistTrainingCoachGuidanceLane GuidanceLaneFromSourceLabel(const FString& SourceLabel)
|
||||
{
|
||||
|
|
@ -352,6 +353,48 @@ namespace HyperTwistTrainingCoachLibraryInternal
|
|||
}
|
||||
}
|
||||
|
||||
FString DescribeCoachFocusTargetLabel(
|
||||
const FString& FocusDeckId,
|
||||
const FString& FocusMethodSegmentId)
|
||||
{
|
||||
if (!FocusDeckId.IsEmpty() && !FocusMethodSegmentId.IsEmpty())
|
||||
{
|
||||
return FString::Printf(
|
||||
TEXT("deck %s | method %s"),
|
||||
*FocusDeckId,
|
||||
*FocusMethodSegmentId
|
||||
);
|
||||
}
|
||||
if (!FocusDeckId.IsEmpty())
|
||||
{
|
||||
return FString::Printf(TEXT("deck %s"), *FocusDeckId);
|
||||
}
|
||||
if (!FocusMethodSegmentId.IsEmpty())
|
||||
{
|
||||
return FString::Printf(TEXT("method %s"), *FocusMethodSegmentId);
|
||||
}
|
||||
|
||||
return TEXT("no focused coach target");
|
||||
}
|
||||
|
||||
FString DescribeGameplayCoachSourceLabel(const FString& SourceLabel)
|
||||
{
|
||||
if (SourceLabel.IsEmpty())
|
||||
{
|
||||
return TEXT("n/a");
|
||||
}
|
||||
if (SourceLabel.StartsWith(TEXT("coach-panel-")))
|
||||
{
|
||||
return TEXT("panel-surface coach action routing");
|
||||
}
|
||||
if (SourceLabel.StartsWith(TEXT("coach-session-actor-")))
|
||||
{
|
||||
return TEXT("session-actor coach action routing");
|
||||
}
|
||||
|
||||
return DescribeCoachMemorySourceLabel(SourceLabel);
|
||||
}
|
||||
|
||||
FString DescribePrimaryCoachActionLabel(
|
||||
const FHyperTwistTrainingCoachPanelState& PanelState,
|
||||
const EHyperTwistTrainingCoachHandoffKind ActionKind
|
||||
|
|
@ -5968,3 +6011,161 @@ UHyperTwistTrainingCoachLibrary::DeriveCoachHandoffContinuationSurface(
|
|||
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachFocusProvenanceSurface
|
||||
UHyperTwistTrainingCoachLibrary::DeriveCoachFocusProvenanceSurface(
|
||||
const FHyperTwistTrainingCoachPanelState& PanelState,
|
||||
const FHyperTwistTrainingCoachPrimaryActionSurface& PrimaryActionSurface,
|
||||
const FHyperTwistTrainingCoachQueueControlSurface& QueueControlSurface,
|
||||
const FHyperTwistTrainingCoachQueueRecoveryPostureSurface& QueueRecoveryPostureSurface,
|
||||
const FHyperTwistTrainingCoachHandoffContinuationSurface& HandoffContinuationSurface
|
||||
)
|
||||
{
|
||||
FHyperTwistTrainingCoachFocusProvenanceSurface Surface;
|
||||
Surface.Headline = TEXT("Coach Focus");
|
||||
Surface.FocusHeadline = !PrimaryActionSurface.Headline.IsEmpty()
|
||||
? PrimaryActionSurface.Headline
|
||||
: PanelState.Headline;
|
||||
Surface.FocusDeckId = !PrimaryActionSurface.FocusDeckId.IsEmpty()
|
||||
? PrimaryActionSurface.FocusDeckId
|
||||
: PanelState.FocusDeckId;
|
||||
Surface.FocusMethodSegmentId = !PrimaryActionSurface.FocusMethodSegmentId.IsEmpty()
|
||||
? PrimaryActionSurface.FocusMethodSegmentId
|
||||
: PanelState.FocusMethodSegmentId;
|
||||
Surface.ContinuationKind = HandoffContinuationSurface.ContinuationKind;
|
||||
Surface.QueuePostureKind = QueueRecoveryPostureSurface.PostureKind;
|
||||
Surface.PreferredGuidanceLane = PanelState.PreferredGuidanceLane;
|
||||
Surface.bHasFocusTarget =
|
||||
!Surface.FocusDeckId.IsEmpty() || !Surface.FocusMethodSegmentId.IsEmpty();
|
||||
|
||||
if (HandoffContinuationSurface.bQueueRecoveryOverridesContinuation)
|
||||
{
|
||||
if (QueueRecoveryPostureSurface.PostureKind
|
||||
== EHyperTwistTrainingCoachQueuePostureKind::Promote)
|
||||
{
|
||||
Surface.ActiveActionLabel = QueueControlSurface.PromoteActionLabel;
|
||||
Surface.ActiveSourceLabel = !QueueControlSurface.PromoteActionSourceLabel.IsEmpty()
|
||||
? QueueControlSurface.PromoteActionSourceLabel
|
||||
: (!QueueRecoveryPostureSurface.PreferredActionSourceLabel.IsEmpty()
|
||||
? QueueRecoveryPostureSurface.PreferredActionSourceLabel
|
||||
: PanelState.PreferredQueueRecoveryActionSourceLabel);
|
||||
}
|
||||
else if (QueueRecoveryPostureSurface.PostureKind
|
||||
== EHyperTwistTrainingCoachQueuePostureKind::Defer)
|
||||
{
|
||||
Surface.ActiveActionLabel = QueueControlSurface.DeferActionLabel;
|
||||
Surface.ActiveSourceLabel = !QueueRecoveryPostureSurface.PreferredActionSourceLabel.IsEmpty()
|
||||
? QueueRecoveryPostureSurface.PreferredActionSourceLabel
|
||||
: (!PanelState.PreferredQueueRecoveryActionSourceLabel.IsEmpty()
|
||||
? PanelState.PreferredQueueRecoveryActionSourceLabel
|
||||
: PanelState.PreferredCoachHandoffSourceLabel);
|
||||
}
|
||||
}
|
||||
else if (HandoffContinuationSurface.bHasActionableContinuation)
|
||||
{
|
||||
Surface.ActiveActionLabel = HandoffContinuationSurface.ContinuationActionLabel;
|
||||
Surface.ActiveSourceLabel = !HandoffContinuationSurface.ContinuationSourceLabel.IsEmpty()
|
||||
? HandoffContinuationSurface.ContinuationSourceLabel
|
||||
: PanelState.PreferredCoachHandoffSourceLabel;
|
||||
}
|
||||
else if (QueueRecoveryPostureSurface.bCanExecutePreferredAction)
|
||||
{
|
||||
Surface.ActiveActionLabel = QueueRecoveryPostureSurface.PreferredActionLabel;
|
||||
Surface.ActiveSourceLabel = !QueueRecoveryPostureSurface.PreferredActionSourceLabel.IsEmpty()
|
||||
? QueueRecoveryPostureSurface.PreferredActionSourceLabel
|
||||
: PanelState.PreferredQueueRecoveryActionSourceLabel;
|
||||
}
|
||||
|
||||
Surface.ActiveSourceDescription =
|
||||
HyperTwistTrainingCoachLibraryInternal::DescribeGameplayCoachSourceLabel(
|
||||
Surface.ActiveSourceLabel
|
||||
);
|
||||
Surface.GuidanceSourceDescription =
|
||||
HyperTwistTrainingCoachLibraryInternal::DescribeGameplayCoachSourceLabel(
|
||||
PanelState.PreferredGuidanceSourceLabel
|
||||
);
|
||||
Surface.HandoffSourceDescription =
|
||||
HyperTwistTrainingCoachLibraryInternal::DescribeGameplayCoachSourceLabel(
|
||||
PanelState.PreferredCoachHandoffSourceLabel
|
||||
);
|
||||
Surface.QueueSourceDescription =
|
||||
HyperTwistTrainingCoachLibraryInternal::DescribeGameplayCoachSourceLabel(
|
||||
PanelState.NextQueueSourceLabel
|
||||
);
|
||||
Surface.RecoverySourceDescription =
|
||||
HyperTwistTrainingCoachLibraryInternal::DescribeGameplayCoachSourceLabel(
|
||||
PanelState.PreferredQueueRecoveryActionSourceLabel
|
||||
);
|
||||
Surface.LaunchBudgetSourceDescription =
|
||||
HyperTwistTrainingCoachLibraryInternal::DescribeGameplayCoachSourceLabel(
|
||||
PanelState.PreferredLaunchBudgetSourceLabel
|
||||
);
|
||||
Surface.bHasUpstreamProvenance =
|
||||
!Surface.ActiveSourceLabel.IsEmpty()
|
||||
|| !PanelState.PreferredGuidanceSourceLabel.IsEmpty()
|
||||
|| !PanelState.PreferredCoachHandoffSourceLabel.IsEmpty()
|
||||
|| !PanelState.NextQueueSourceLabel.IsEmpty()
|
||||
|| !PanelState.PreferredQueueRecoveryActionSourceLabel.IsEmpty()
|
||||
|| !PanelState.PreferredLaunchBudgetSourceLabel.IsEmpty();
|
||||
|
||||
const FString FocusTargetLabel = HyperTwistTrainingCoachLibraryInternal::DescribeCoachFocusTargetLabel(
|
||||
Surface.FocusDeckId,
|
||||
Surface.FocusMethodSegmentId
|
||||
);
|
||||
const FString ContinuationKindLabel =
|
||||
HyperTwistTrainingCoachLibraryInternal::DescribeCoachHandoffKind(
|
||||
Surface.ContinuationKind
|
||||
);
|
||||
const FString QueuePostureLabel =
|
||||
HyperTwistTrainingCoachLibraryInternal::DescribeCoachQueuePostureKind(
|
||||
Surface.QueuePostureKind
|
||||
);
|
||||
const FString GuidanceLaneLabel = HyperTwistTrainingCoachLibraryInternal::DescribeGuidanceLane(
|
||||
Surface.PreferredGuidanceLane
|
||||
);
|
||||
|
||||
Surface.FocusSummaryLine = FString::Printf(
|
||||
TEXT("Focus target: %s | Active action: %s | Continuation: %s"),
|
||||
*FocusTargetLabel,
|
||||
Surface.ActiveActionLabel.IsEmpty() ? TEXT("none") : *Surface.ActiveActionLabel,
|
||||
*ContinuationKindLabel
|
||||
);
|
||||
if (!Surface.FocusHeadline.IsEmpty())
|
||||
{
|
||||
Surface.FocusSummaryLine += FString::Printf(
|
||||
TEXT(" | Headline: %s"),
|
||||
*Surface.FocusHeadline
|
||||
);
|
||||
}
|
||||
|
||||
Surface.ProvenanceSummaryLine = FString::Printf(
|
||||
TEXT("Active provenance: %s | Guidance: %s | Handoff: %s | Recovery: %s"),
|
||||
*Surface.ActiveSourceDescription,
|
||||
*Surface.GuidanceSourceDescription,
|
||||
*Surface.HandoffSourceDescription,
|
||||
*Surface.RecoverySourceDescription
|
||||
);
|
||||
|
||||
Surface.DetailLine = FString::Printf(
|
||||
TEXT("Queue posture: %s | Preferred lane: %s | Queue source: %s | Launch budget source: %s | Handoff status: %s | Queue recovery: %s"),
|
||||
*QueuePostureLabel,
|
||||
*GuidanceLaneLabel,
|
||||
*Surface.QueueSourceDescription,
|
||||
*Surface.LaunchBudgetSourceDescription,
|
||||
HandoffContinuationSurface.StatusLine.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: *HandoffContinuationSurface.StatusLine,
|
||||
QueueRecoveryPostureSurface.StatusLine.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: *QueueRecoveryPostureSurface.StatusLine
|
||||
);
|
||||
if (!HandoffContinuationSurface.DetailLine.IsEmpty())
|
||||
{
|
||||
Surface.DetailLine += FString::Printf(
|
||||
TEXT(" | Continuation detail: %s"),
|
||||
*HandoffContinuationSurface.DetailLine
|
||||
);
|
||||
}
|
||||
|
||||
return Surface;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -490,6 +490,37 @@ UHyperTwistTrainingPanelWidget::GetDisplayedCoachHandoffContinuationSurface() co
|
|||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachFocusProvenanceSurface
|
||||
UHyperTwistTrainingPanelWidget::GetDisplayedCoachFocusProvenanceSurface() const
|
||||
{
|
||||
const FHyperTwistTrainingCoachPrimaryActionSurface PrimaryActionSurface =
|
||||
GetDisplayedPrimaryCoachActionSurface();
|
||||
const FHyperTwistTrainingCoachQueueControlSurface QueueControlSurface =
|
||||
GetDisplayedCoachQueueControlSurface();
|
||||
const FHyperTwistTrainingCoachQueueRecoveryPostureSurface QueueRecoveryPostureSurface =
|
||||
UHyperTwistTrainingCoachLibrary::DeriveCoachQueueRecoveryPostureSurface(
|
||||
CachedCoachSchedulePolicySummary,
|
||||
CachedCoachQueueExecutionSummary,
|
||||
CachedCoachPanelState,
|
||||
PrimaryActionSurface,
|
||||
QueueControlSurface
|
||||
);
|
||||
const FHyperTwistTrainingCoachHandoffContinuationSurface HandoffContinuationSurface =
|
||||
UHyperTwistTrainingCoachLibrary::DeriveCoachHandoffContinuationSurface(
|
||||
CachedCoachPanelState,
|
||||
PrimaryActionSurface,
|
||||
QueueControlSurface,
|
||||
QueueRecoveryPostureSurface
|
||||
);
|
||||
return UHyperTwistTrainingCoachLibrary::DeriveCoachFocusProvenanceSurface(
|
||||
CachedCoachPanelState,
|
||||
PrimaryActionSurface,
|
||||
QueueControlSurface,
|
||||
QueueRecoveryPostureSurface,
|
||||
HandoffContinuationSurface
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartCoachRecommendedRun(
|
||||
const int32 MaxCases,
|
||||
const FString& StartActionSourceLabel
|
||||
|
|
|
|||
|
|
@ -471,6 +471,37 @@ AHyperTwistTrainingSessionActor::GetDisplayedCoachHandoffContinuationSurface() c
|
|||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachFocusProvenanceSurface
|
||||
AHyperTwistTrainingSessionActor::GetDisplayedCoachFocusProvenanceSurface() const
|
||||
{
|
||||
const FHyperTwistTrainingCoachPrimaryActionSurface PrimaryActionSurface =
|
||||
GetDisplayedPrimaryCoachActionSurface();
|
||||
const FHyperTwistTrainingCoachQueueControlSurface QueueControlSurface =
|
||||
GetDisplayedCoachQueueControlSurface();
|
||||
const FHyperTwistTrainingCoachQueueRecoveryPostureSurface QueueRecoveryPostureSurface =
|
||||
UHyperTwistTrainingCoachLibrary::DeriveCoachQueueRecoveryPostureSurface(
|
||||
CachedCoachSchedulePolicySummary,
|
||||
CachedCoachQueueExecutionSummary,
|
||||
CachedCoachPanelState,
|
||||
PrimaryActionSurface,
|
||||
QueueControlSurface
|
||||
);
|
||||
const FHyperTwistTrainingCoachHandoffContinuationSurface HandoffContinuationSurface =
|
||||
UHyperTwistTrainingCoachLibrary::DeriveCoachHandoffContinuationSurface(
|
||||
CachedCoachPanelState,
|
||||
PrimaryActionSurface,
|
||||
QueueControlSurface,
|
||||
QueueRecoveryPostureSurface
|
||||
);
|
||||
return UHyperTwistTrainingCoachLibrary::DeriveCoachFocusProvenanceSurface(
|
||||
CachedCoachPanelState,
|
||||
PrimaryActionSurface,
|
||||
QueueControlSurface,
|
||||
QueueRecoveryPostureSurface,
|
||||
HandoffContinuationSurface
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartCoachRecommendedTrainingRun(
|
||||
const int32 MaxCases
|
||||
)
|
||||
|
|
|
|||
|
|
@ -619,4 +619,14 @@ public:
|
|||
const FHyperTwistTrainingCoachQueueControlSurface& QueueControlSurface,
|
||||
const FHyperTwistTrainingCoachQueueRecoveryPostureSurface& QueueRecoveryPostureSurface
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
static FHyperTwistTrainingCoachFocusProvenanceSurface
|
||||
DeriveCoachFocusProvenanceSurface(
|
||||
const FHyperTwistTrainingCoachPanelState& PanelState,
|
||||
const FHyperTwistTrainingCoachPrimaryActionSurface& PrimaryActionSurface,
|
||||
const FHyperTwistTrainingCoachQueueControlSurface& QueueControlSurface,
|
||||
const FHyperTwistTrainingCoachQueueRecoveryPostureSurface& QueueRecoveryPostureSurface,
|
||||
const FHyperTwistTrainingCoachHandoffContinuationSurface& HandoffContinuationSurface
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -228,6 +228,10 @@ public:
|
|||
FHyperTwistTrainingCoachHandoffContinuationSurface
|
||||
GetDisplayedCoachHandoffContinuationSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingCoachFocusProvenanceSurface
|
||||
GetDisplayedCoachFocusProvenanceSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartCoachRecommendedRun(
|
||||
int32 MaxCases,
|
||||
|
|
|
|||
|
|
@ -209,6 +209,10 @@ public:
|
|||
FHyperTwistTrainingCoachHandoffContinuationSurface
|
||||
GetDisplayedCoachHandoffContinuationSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingCoachFocusProvenanceSurface
|
||||
GetDisplayedCoachFocusProvenanceSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartCoachRecommendedTrainingRun(int32 MaxCases);
|
||||
|
||||
|
|
|
|||
|
|
@ -8016,3 +8016,80 @@ struct FHyperTwistTrainingCoachHandoffContinuationSurface
|
|||
|| !QueueRecoveryStatusLine.IsEmpty();
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachFocusProvenanceSurface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString Headline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString FocusHeadline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString FocusSummaryLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString ProvenanceSummaryLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString FocusDeckId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString FocusMethodSegmentId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString ActiveActionLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString ActiveSourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString ActiveSourceDescription;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString GuidanceSourceDescription;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString HandoffSourceDescription;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString QueueSourceDescription;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString RecoverySourceDescription;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString LaunchBudgetSourceDescription;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
EHyperTwistTrainingCoachHandoffKind ContinuationKind =
|
||||
EHyperTwistTrainingCoachHandoffKind::None;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
EHyperTwistTrainingCoachQueuePostureKind QueuePostureKind =
|
||||
EHyperTwistTrainingCoachQueuePostureKind::None;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
EHyperTwistTrainingCoachGuidanceLane PreferredGuidanceLane =
|
||||
EHyperTwistTrainingCoachGuidanceLane::None;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasFocusTarget = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasUpstreamProvenance = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !FocusSummaryLine.IsEmpty()
|
||||
|| !ProvenanceSummaryLine.IsEmpty()
|
||||
|| bHasFocusTarget
|
||||
|| bHasUpstreamProvenance;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 coach handoff recommendation / continuation status surface over the already-landed primary CTA, secondary queue-control, and queue-recovery posture surfaces, so gameplay/Blueprint callers can render the queued-vs-follow-up-vs-recommended continuation posture without reaching into raw panel-state strings or handoff enums directly
|
||||
- the current next bounded packet is to expose one thin coach focus/provenance summary surface on those same two consumer surfaces so gameplay/Blueprint callers can render the active coach target and upstream recommendation provenance without reading raw focus ids or source-label strings directly
|
||||
- the latest landed bounded `Phase 4` packet stays on that same gameplay-facing consumer lane and adds one thin coach focus/provenance summary surface over the already-landed primary CTA, secondary queue-control, queue-recovery posture, and handoff-continuation surfaces, so gameplay/Blueprint callers can render the active coach target and upstream recommendation provenance without reading raw focus ids or source-label strings directly
|
||||
- the current next bounded packet is to expose one thin coach workload/budget summary surface on those same two consumer surfaces so gameplay/Blueprint callers can render launch case budget, queue load, and focus pressure without reading raw count and budget fields 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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,114 @@
|
|||
# HyperTwist Phase 4 gameplay focus provenance surface packet
|
||||
|
||||
Created on `2026-05-07`
|
||||
|
||||
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 coach helpers by exposing one pure focus/provenance summary surface over the already-landed primary coach CTA, queue-control, queue-recovery posture, and handoff-continuation surfaces.
|
||||
|
||||
The open tasks were:
|
||||
|
||||
- stop forcing gameplay / Blueprint callers to read raw focus deck ids, focus method-segment ids, and source-label strings just to describe the active coach target and why it is the active target
|
||||
- expose one thin first-party focus/provenance surface that summarizes the current coach target, the active action provenance, and the upstream guidance / handoff / recovery / launch-budget sources
|
||||
- keep that surface derived from already-cached gameplay consumer state instead of widening into dashboard-only provenance composition or retained recommendation history
|
||||
|
||||
It is not:
|
||||
|
||||
- a new recommendation policy packet
|
||||
- a dashboard provenance migration
|
||||
- a broader gameplay HUD composition pass
|
||||
- a backend continuity or template-analytics packet
|
||||
|
||||
## Scope
|
||||
|
||||
Bounded lane:
|
||||
|
||||
- add a first-party focus/provenance surface in shared training types
|
||||
- add a coach-library helper that derives the surface from panel state, the displayed primary CTA surface, the displayed queue-control surface, the displayed queue-recovery posture surface, and the displayed handoff-continuation surface
|
||||
- expose that derived focus/provenance surface on `HyperTwistTrainingPanelWidget` and `HyperTwistTrainingSessionActor`
|
||||
- keep the derivation presentation-only and rooted in already-cached gameplay consumer state
|
||||
|
||||
Out of scope:
|
||||
|
||||
- importing the dashboard’s deeper retained provenance views into gameplay consumers
|
||||
- changing coach handoff branch order
|
||||
- changing queue recovery policy
|
||||
- widening into broader gameplay orchestration in the same packet
|
||||
|
||||
## Why this was the right next packet
|
||||
|
||||
Before this slice:
|
||||
|
||||
- gameplay-facing panel/session consumers already exposed a truthful primary CTA surface
|
||||
- those surfaces already exposed truthful queue-control, queue-recovery posture, and handoff-continuation surfaces
|
||||
|
||||
But one thin consumer seam was still open:
|
||||
|
||||
- callers could bind actions and narrate continuation posture
|
||||
- but they still had to inspect raw focus ids and source-label strings to explain what the current coach target actually was and what upstream path produced it
|
||||
|
||||
That meant:
|
||||
|
||||
- action binding was thin
|
||||
- continuation posture was thin
|
||||
- but target/provenance explanation still leaked raw state into callers
|
||||
|
||||
So the next bounded move was:
|
||||
|
||||
- keep the already-landed action and posture surfaces unchanged
|
||||
- and expose one narrow focus/provenance summary surface above them
|
||||
|
||||
## What landed
|
||||
|
||||
Primary code changes:
|
||||
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h`
|
||||
- added `FHyperTwistTrainingCoachFocusProvenanceSurface`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp`
|
||||
- added `DeriveCoachFocusProvenanceSurface(...)`
|
||||
- focus/provenance is derived from existing panel-state, primary CTA, queue-control, queue-recovery posture, and handoff-continuation inputs
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp`
|
||||
- added `GetDisplayedCoachFocusProvenanceSurface()`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp`
|
||||
- added `GetDisplayedCoachFocusProvenanceSurface()`
|
||||
|
||||
## Product effect
|
||||
|
||||
The gameplay-facing coach consumer layer is now more complete:
|
||||
|
||||
- gameplay / Blueprint callers can read one pure surface to describe the active coach target and its upstream provenance
|
||||
- callers no longer need to inspect raw focus ids and source-label strings just to render target/provenance narration
|
||||
- the surface stays aligned with the already-landed primary CTA, queue-control, queue-recovery posture, and handoff-continuation surfaces without importing dashboard-only retained provenance composition
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- shared training types expose a narrow focus/provenance surface
|
||||
- coach-library derivation consumes the already-cached gameplay consumer state rather than adding new runtime fetches
|
||||
- panel-widget callers can fetch the displayed focus/provenance surface directly
|
||||
- session-actor callers can fetch the displayed focus/provenance surface directly
|
||||
- full product build succeeds
|
||||
|
||||
## Validation checklist
|
||||
|
||||
1. build `UnrealHyperTwist.sln` / `UnrealHyperTwistEditor`
|
||||
2. confirm the new focus/provenance surface compiles in shared types and coach library
|
||||
3. confirm panel-widget getters compile and return the derived focus/provenance surface
|
||||
4. confirm session-actor getters compile and return the derived focus/provenance surface
|
||||
5. confirm no backend continuity or dashboard-only provenance composition was pulled into the packet
|
||||
|
||||
## Validation result
|
||||
|
||||
- full `Development Editor|Win64` build succeeded on `2026-05-07`
|
||||
- build completed with `0` warnings and `0` errors
|
||||
|
||||
## Next bounded follow-on slice
|
||||
|
||||
- stay on the same gameplay-facing consumer lane and expose one thin coach workload/budget summary surface on `HyperTwistTrainingPanelWidget` and `HyperTwistTrainingSessionActor`, so gameplay callers can render launch case budget, queue load, and focus pressure without reading raw count and budget fields directly
|
||||
Loading…
Add table
Reference in a new issue