Expose gameplay handoff continuation surface
This commit is contained in:
parent
82b470b02b
commit
0d813df46b
9 changed files with 433 additions and 15 deletions
|
|
@ -323,6 +323,35 @@ namespace HyperTwistTrainingCoachLibraryInternal
|
|||
}
|
||||
}
|
||||
|
||||
FString DescribeCoachQueuePostureKind(
|
||||
const EHyperTwistTrainingCoachQueuePostureKind PostureKind)
|
||||
{
|
||||
switch (PostureKind)
|
||||
{
|
||||
case EHyperTwistTrainingCoachQueuePostureKind::Continue:
|
||||
return TEXT("continue");
|
||||
case EHyperTwistTrainingCoachQueuePostureKind::Defer:
|
||||
return TEXT("defer");
|
||||
case EHyperTwistTrainingCoachQueuePostureKind::Promote:
|
||||
return TEXT("promote");
|
||||
default:
|
||||
return TEXT("none");
|
||||
}
|
||||
}
|
||||
|
||||
FString DescribeGuidanceLane(const EHyperTwistTrainingCoachGuidanceLane Lane)
|
||||
{
|
||||
switch (Lane)
|
||||
{
|
||||
case EHyperTwistTrainingCoachGuidanceLane::FollowUp:
|
||||
return TEXT("follow-up");
|
||||
case EHyperTwistTrainingCoachGuidanceLane::Recommended:
|
||||
return TEXT("recommended");
|
||||
default:
|
||||
return TEXT("none");
|
||||
}
|
||||
}
|
||||
|
||||
FString DescribePrimaryCoachActionLabel(
|
||||
const FHyperTwistTrainingCoachPanelState& PanelState,
|
||||
const EHyperTwistTrainingCoachHandoffKind ActionKind
|
||||
|
|
@ -5581,18 +5610,6 @@ UHyperTwistTrainingCoachLibrary::DeriveCoachQueueRecoveryPostureSurface(
|
|||
const FHyperTwistTrainingCoachQueueControlSurface& QueueControlSurface
|
||||
)
|
||||
{
|
||||
auto DescribeGuidanceLane = [](const EHyperTwistTrainingCoachGuidanceLane Lane) -> FString
|
||||
{
|
||||
switch (Lane)
|
||||
{
|
||||
case EHyperTwistTrainingCoachGuidanceLane::FollowUp:
|
||||
return TEXT("follow-up");
|
||||
case EHyperTwistTrainingCoachGuidanceLane::Recommended:
|
||||
return TEXT("recommended");
|
||||
default:
|
||||
return TEXT("none");
|
||||
}
|
||||
};
|
||||
auto DescribeRecoveryAction = [](const EHyperTwistTrainingQueueRecoveryAction Action) -> FString
|
||||
{
|
||||
switch (Action)
|
||||
|
|
@ -5738,7 +5755,9 @@ UHyperTwistTrainingCoachLibrary::DeriveCoachQueueRecoveryPostureSurface(
|
|||
break;
|
||||
}
|
||||
|
||||
const FString GuidanceLaneLabel = DescribeGuidanceLane(PanelState.PreferredGuidanceLane);
|
||||
const FString GuidanceLaneLabel = HyperTwistTrainingCoachLibraryInternal::DescribeGuidanceLane(
|
||||
PanelState.PreferredGuidanceLane
|
||||
);
|
||||
const FString GuidanceSourceLabel = PanelState.PreferredGuidanceSourceLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: HyperTwistTrainingCoachLibraryInternal::DescribeCoachMemorySourceLabel(
|
||||
|
|
@ -5777,3 +5796,175 @@ UHyperTwistTrainingCoachLibrary::DeriveCoachQueueRecoveryPostureSurface(
|
|||
|
||||
return Surface;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachHandoffContinuationSurface
|
||||
UHyperTwistTrainingCoachLibrary::DeriveCoachHandoffContinuationSurface(
|
||||
const FHyperTwistTrainingCoachPanelState& PanelState,
|
||||
const FHyperTwistTrainingCoachPrimaryActionSurface& PrimaryActionSurface,
|
||||
const FHyperTwistTrainingCoachQueueControlSurface& QueueControlSurface,
|
||||
const FHyperTwistTrainingCoachQueueRecoveryPostureSurface& QueueRecoveryPostureSurface
|
||||
)
|
||||
{
|
||||
FHyperTwistTrainingCoachHandoffContinuationSurface Surface;
|
||||
Surface.Headline = TEXT("Coach Handoff");
|
||||
Surface.ContinuationKind = PrimaryActionSurface.ActionKind;
|
||||
Surface.QueuePostureKind = QueueRecoveryPostureSurface.PostureKind;
|
||||
Surface.bHasActionableContinuation = PrimaryActionSurface.bCanExecute;
|
||||
Surface.ContinuationActionLabel = PrimaryActionSurface.bCanExecute
|
||||
? PrimaryActionSurface.ActionLabel
|
||||
: FString();
|
||||
Surface.ContinuationAvailabilityLine = PrimaryActionSurface.AvailabilityLine;
|
||||
Surface.ContinuationSourceLabel = PrimaryActionSurface.bCanExecute
|
||||
? PrimaryActionSurface.ActionSourceLabel
|
||||
: FString();
|
||||
Surface.QueueRecoveryStatusLine = QueueRecoveryPostureSurface.StatusLine;
|
||||
Surface.bQueueRecoveryOverridesContinuation =
|
||||
PrimaryActionSurface.bCanExecute
|
||||
&& (QueueRecoveryPostureSurface.PostureKind
|
||||
== EHyperTwistTrainingCoachQueuePostureKind::Promote
|
||||
|| QueueRecoveryPostureSurface.PostureKind
|
||||
== EHyperTwistTrainingCoachQueuePostureKind::Defer);
|
||||
|
||||
const FString ContinuationKindLabel =
|
||||
HyperTwistTrainingCoachLibraryInternal::DescribeCoachHandoffKind(
|
||||
PrimaryActionSurface.ActionKind
|
||||
);
|
||||
const FString QueuePostureLabel =
|
||||
HyperTwistTrainingCoachLibraryInternal::DescribeCoachQueuePostureKind(
|
||||
QueueRecoveryPostureSurface.PostureKind
|
||||
);
|
||||
const FString GuidanceLaneLabel = HyperTwistTrainingCoachLibraryInternal::DescribeGuidanceLane(
|
||||
PanelState.PreferredGuidanceLane
|
||||
);
|
||||
const FString ContinuationSourceDescription = Surface.ContinuationSourceLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: HyperTwistTrainingCoachLibraryInternal::DescribeCoachMemorySourceLabel(
|
||||
Surface.ContinuationSourceLabel
|
||||
);
|
||||
const FString PreferredHandoffSourceDescription = PanelState.PreferredCoachHandoffSourceLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: HyperTwistTrainingCoachLibraryInternal::DescribeCoachMemorySourceLabel(
|
||||
PanelState.PreferredCoachHandoffSourceLabel
|
||||
);
|
||||
|
||||
if (Surface.bQueueRecoveryOverridesContinuation)
|
||||
{
|
||||
Surface.StatusLine =
|
||||
QueueRecoveryPostureSurface.PostureKind
|
||||
== EHyperTwistTrainingCoachQueuePostureKind::Promote
|
||||
? FString::Printf(
|
||||
TEXT("Continuation: %s coach work is ready, but queue recovery prefers deferred promotion before another run."),
|
||||
*ContinuationKindLabel
|
||||
)
|
||||
: FString::Printf(
|
||||
TEXT("Continuation: %s coach work is ready, but queue recovery is currently holding the next step on defer control."),
|
||||
*ContinuationKindLabel
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (PrimaryActionSurface.ActionKind)
|
||||
{
|
||||
case EHyperTwistTrainingCoachHandoffKind::Queue:
|
||||
Surface.StatusLine = FString::Printf(
|
||||
TEXT("Continuation: queued coach work is the live next handoff. Source: %s"),
|
||||
*ContinuationSourceDescription
|
||||
);
|
||||
break;
|
||||
case EHyperTwistTrainingCoachHandoffKind::FollowUp:
|
||||
Surface.StatusLine = FString::Printf(
|
||||
TEXT("Continuation: follow-up coach work is the live next handoff. Source: %s"),
|
||||
*ContinuationSourceDescription
|
||||
);
|
||||
break;
|
||||
case EHyperTwistTrainingCoachHandoffKind::Recommended:
|
||||
Surface.StatusLine = FString::Printf(
|
||||
TEXT("Continuation: recommended coach work is the live next handoff. Source: %s"),
|
||||
*ContinuationSourceDescription
|
||||
);
|
||||
break;
|
||||
default:
|
||||
if (QueueRecoveryPostureSurface.PostureKind
|
||||
== EHyperTwistTrainingCoachQueuePostureKind::Promote)
|
||||
{
|
||||
Surface.StatusLine = TEXT(
|
||||
"Continuation: no queued, follow-up, or recommended coach run is currently actionable; queue recovery prefers deferred promotion next."
|
||||
);
|
||||
}
|
||||
else if (QueueRecoveryPostureSurface.PostureKind
|
||||
== EHyperTwistTrainingCoachQueuePostureKind::Defer)
|
||||
{
|
||||
Surface.StatusLine = TEXT(
|
||||
"Continuation: no queued, follow-up, or recommended coach run is currently actionable; defer is the available queue-recovery control."
|
||||
);
|
||||
}
|
||||
else if (PanelState.bHasActiveRun)
|
||||
{
|
||||
Surface.StatusLine = TEXT(
|
||||
"Continuation: finish or clear the active run before another coach handoff becomes actionable."
|
||||
);
|
||||
}
|
||||
else if (QueueRecoveryPostureSurface.bHasRecoveryPressure)
|
||||
{
|
||||
Surface.StatusLine = TEXT(
|
||||
"Continuation: no queued, follow-up, or recommended coach run is currently actionable; queue recovery pressure remains active."
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Surface.StatusLine = TEXT(
|
||||
"Continuation: no queued, follow-up, or recommended coach run is currently actionable."
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Surface.DetailLine = FString::Printf(
|
||||
TEXT("Live continuation: %s | Primary CTA: %s | Availability: %s | Queue posture: %s | Queue recovery: %s | Preferred handoff: %s from %s | Guidance lane: %s"),
|
||||
*ContinuationKindLabel,
|
||||
PrimaryActionSurface.bCanExecute
|
||||
&& !PrimaryActionSurface.ActionLabel.IsEmpty()
|
||||
? *PrimaryActionSurface.ActionLabel
|
||||
: TEXT("n/a"),
|
||||
PrimaryActionSurface.AvailabilityLine.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: *PrimaryActionSurface.AvailabilityLine,
|
||||
*QueuePostureLabel,
|
||||
QueueRecoveryPostureSurface.StatusLine.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: *QueueRecoveryPostureSurface.StatusLine,
|
||||
*HyperTwistTrainingCoachLibraryInternal::DescribeCoachHandoffKind(
|
||||
PanelState.PreferredCoachHandoffKind
|
||||
),
|
||||
*PreferredHandoffSourceDescription,
|
||||
*GuidanceLaneLabel
|
||||
);
|
||||
if (!PrimaryActionSurface.DetailLine.IsEmpty())
|
||||
{
|
||||
Surface.DetailLine += FString::Printf(
|
||||
TEXT(" | Primary detail: %s"),
|
||||
*PrimaryActionSurface.DetailLine
|
||||
);
|
||||
}
|
||||
if (QueueRecoveryPostureSurface.PostureKind
|
||||
== EHyperTwistTrainingCoachQueuePostureKind::Promote
|
||||
&& !QueueControlSurface.PromoteAvailabilityLine.IsEmpty())
|
||||
{
|
||||
Surface.DetailLine += FString::Printf(
|
||||
TEXT(" | Promote: %s"),
|
||||
*QueueControlSurface.PromoteAvailabilityLine
|
||||
);
|
||||
}
|
||||
else if (QueueRecoveryPostureSurface.PostureKind
|
||||
== EHyperTwistTrainingCoachQueuePostureKind::Defer
|
||||
&& !QueueControlSurface.DeferAvailabilityLine.IsEmpty())
|
||||
{
|
||||
Surface.DetailLine += FString::Printf(
|
||||
TEXT(" | Defer: %s"),
|
||||
*QueueControlSurface.DeferAvailabilityLine
|
||||
);
|
||||
}
|
||||
|
||||
return Surface;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -467,6 +467,29 @@ UHyperTwistTrainingPanelWidget::GetDisplayedCoachQueueRecoveryPostureSurface() c
|
|||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachHandoffContinuationSurface
|
||||
UHyperTwistTrainingPanelWidget::GetDisplayedCoachHandoffContinuationSurface() const
|
||||
{
|
||||
const FHyperTwistTrainingCoachPrimaryActionSurface PrimaryActionSurface =
|
||||
GetDisplayedPrimaryCoachActionSurface();
|
||||
const FHyperTwistTrainingCoachQueueControlSurface QueueControlSurface =
|
||||
GetDisplayedCoachQueueControlSurface();
|
||||
const FHyperTwistTrainingCoachQueueRecoveryPostureSurface QueueRecoveryPostureSurface =
|
||||
UHyperTwistTrainingCoachLibrary::DeriveCoachQueueRecoveryPostureSurface(
|
||||
CachedCoachSchedulePolicySummary,
|
||||
CachedCoachQueueExecutionSummary,
|
||||
CachedCoachPanelState,
|
||||
PrimaryActionSurface,
|
||||
QueueControlSurface
|
||||
);
|
||||
return UHyperTwistTrainingCoachLibrary::DeriveCoachHandoffContinuationSurface(
|
||||
CachedCoachPanelState,
|
||||
PrimaryActionSurface,
|
||||
QueueControlSurface,
|
||||
QueueRecoveryPostureSurface
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState UHyperTwistTrainingPanelWidget::StartCoachRecommendedRun(
|
||||
const int32 MaxCases,
|
||||
const FString& StartActionSourceLabel
|
||||
|
|
|
|||
|
|
@ -448,6 +448,29 @@ AHyperTwistTrainingSessionActor::GetDisplayedCoachQueueRecoveryPostureSurface()
|
|||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachHandoffContinuationSurface
|
||||
AHyperTwistTrainingSessionActor::GetDisplayedCoachHandoffContinuationSurface() const
|
||||
{
|
||||
const FHyperTwistTrainingCoachPrimaryActionSurface PrimaryActionSurface =
|
||||
GetDisplayedPrimaryCoachActionSurface();
|
||||
const FHyperTwistTrainingCoachQueueControlSurface QueueControlSurface =
|
||||
GetDisplayedCoachQueueControlSurface();
|
||||
const FHyperTwistTrainingCoachQueueRecoveryPostureSurface QueueRecoveryPostureSurface =
|
||||
UHyperTwistTrainingCoachLibrary::DeriveCoachQueueRecoveryPostureSurface(
|
||||
CachedCoachSchedulePolicySummary,
|
||||
CachedCoachQueueExecutionSummary,
|
||||
CachedCoachPanelState,
|
||||
PrimaryActionSurface,
|
||||
QueueControlSurface
|
||||
);
|
||||
return UHyperTwistTrainingCoachLibrary::DeriveCoachHandoffContinuationSurface(
|
||||
CachedCoachPanelState,
|
||||
PrimaryActionSurface,
|
||||
QueueControlSurface,
|
||||
QueueRecoveryPostureSurface
|
||||
);
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRunState AHyperTwistTrainingSessionActor::StartCoachRecommendedTrainingRun(
|
||||
const int32 MaxCases
|
||||
)
|
||||
|
|
|
|||
|
|
@ -610,4 +610,13 @@ public:
|
|||
const FHyperTwistTrainingCoachPrimaryActionSurface& PrimaryActionSurface,
|
||||
const FHyperTwistTrainingCoachQueueControlSurface& QueueControlSurface
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
static FHyperTwistTrainingCoachHandoffContinuationSurface
|
||||
DeriveCoachHandoffContinuationSurface(
|
||||
const FHyperTwistTrainingCoachPanelState& PanelState,
|
||||
const FHyperTwistTrainingCoachPrimaryActionSurface& PrimaryActionSurface,
|
||||
const FHyperTwistTrainingCoachQueueControlSurface& QueueControlSurface,
|
||||
const FHyperTwistTrainingCoachQueueRecoveryPostureSurface& QueueRecoveryPostureSurface
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -224,6 +224,10 @@ public:
|
|||
FHyperTwistTrainingCoachQueueRecoveryPostureSurface
|
||||
GetDisplayedCoachQueueRecoveryPostureSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingCoachHandoffContinuationSurface
|
||||
GetDisplayedCoachHandoffContinuationSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartCoachRecommendedRun(
|
||||
int32 MaxCases,
|
||||
|
|
|
|||
|
|
@ -205,6 +205,10 @@ public:
|
|||
FHyperTwistTrainingCoachQueueRecoveryPostureSurface
|
||||
GetDisplayedCoachQueueRecoveryPostureSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingCoachHandoffContinuationSurface
|
||||
GetDisplayedCoachHandoffContinuationSurface() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Coach")
|
||||
FHyperTwistTrainingRunState StartCoachRecommendedTrainingRun(int32 MaxCases);
|
||||
|
||||
|
|
|
|||
|
|
@ -7967,3 +7967,52 @@ struct FHyperTwistTrainingCoachQueueRecoveryPostureSurface
|
|||
|| bHasRecoveryPressure;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingCoachHandoffContinuationSurface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString Headline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString StatusLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString DetailLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString ContinuationActionLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString ContinuationAvailabilityLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString ContinuationSourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString QueueRecoveryStatusLine;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
EHyperTwistTrainingCoachHandoffKind ContinuationKind =
|
||||
EHyperTwistTrainingCoachHandoffKind::None;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
EHyperTwistTrainingCoachQueuePostureKind QueuePostureKind =
|
||||
EHyperTwistTrainingCoachQueuePostureKind::None;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasActionableContinuation = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bQueueRecoveryOverridesContinuation = false;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return !StatusLine.IsEmpty()
|
||||
|| !DetailLine.IsEmpty()
|
||||
|| bHasActionableContinuation
|
||||
|| !QueueRecoveryStatusLine.IsEmpty();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 queue-recovery posture / status surface over the already-landed primary CTA and secondary queue-control surfaces, so gameplay/Blueprint callers can explain why continue, defer, or promote is preferred without reading raw suppression/status strings or recovery enums directly
|
||||
- the current next bounded packet is to expose one thin coach handoff recommendation / continuation status surface on those same two consumer 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 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 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,115 @@
|
|||
# HyperTwist Phase 4 gameplay handoff continuation 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 handoff recommendation / continuation status surface over the already-landed primary coach CTA, queue-control, and queue-recovery posture surfaces.
|
||||
|
||||
The open tasks were:
|
||||
|
||||
- stop forcing gameplay / Blueprint callers to read raw panel-state handoff enums and continuation strings just to explain whether queued, follow-up, or recommended coach work is live next
|
||||
- expose one thin first-party continuation surface that summarizes the live coach handoff posture, the actionable continuation branch, and the queue-recovery override posture when recovery control takes precedence
|
||||
- keep that continuation surface derived from already-cached gameplay consumer state instead of widening into the dashboard’s deeper retained recommendation-history analytics
|
||||
|
||||
It is not:
|
||||
|
||||
- a new dashboard handoff-weighting packet
|
||||
- a queue recovery policy change
|
||||
- a backend continuity or template-analytics packet
|
||||
- a broader gameplay HUD composition pass
|
||||
|
||||
## Scope
|
||||
|
||||
Bounded lane:
|
||||
|
||||
- add a first-party handoff continuation 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, and the displayed queue-recovery posture surface
|
||||
- expose that derived continuation surface on `HyperTwistTrainingPanelWidget` and `HyperTwistTrainingSessionActor`
|
||||
- keep the continuation derivation presentation-only and rooted in already-cached gameplay consumer state
|
||||
|
||||
Out of scope:
|
||||
|
||||
- importing the dashboard’s deeper retained handoff analytics into gameplay consumers
|
||||
- changing coach handoff branch order
|
||||
- changing queue recovery selection policy
|
||||
- widening into higher-level gameplay UI composition 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 secondary queue-control and queue-recovery posture surfaces
|
||||
|
||||
But one thin consumer seam was still open:
|
||||
|
||||
- callers could bind actions and explain queue recovery
|
||||
- but they still had to inspect raw handoff enums and panel-state continuation strings to explain whether queued, follow-up, or recommended coach work was actually live next
|
||||
|
||||
That meant:
|
||||
|
||||
- action binding was thin
|
||||
- queue recovery posture was thin
|
||||
- but continuation explanation still leaked raw panel-state state into callers
|
||||
|
||||
So the next bounded move was:
|
||||
|
||||
- keep the already-landed control and recovery surfaces unchanged
|
||||
- and expose one narrow continuation status surface above them
|
||||
|
||||
## What landed
|
||||
|
||||
Primary code changes:
|
||||
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h`
|
||||
- added `FHyperTwistTrainingCoachHandoffContinuationSurface`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp`
|
||||
- added `DeriveCoachHandoffContinuationSurface(...)`
|
||||
- continuation posture is derived from existing panel-state, primary CTA, queue-control, and queue-recovery posture inputs
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp`
|
||||
- added `GetDisplayedCoachHandoffContinuationSurface()`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp`
|
||||
- added `GetDisplayedCoachHandoffContinuationSurface()`
|
||||
|
||||
## Product effect
|
||||
|
||||
The gameplay-facing coach consumer layer is now more complete:
|
||||
|
||||
- gameplay / Blueprint callers can read one pure surface to explain whether queued, follow-up, or recommended coach work is the live next continuation branch
|
||||
- callers no longer need to inspect raw panel-state handoff enums or handoff status strings just to narrate continuation posture
|
||||
- the surface also carries the queue-recovery override posture when deferred promotion or defer control takes precedence over immediately starting another run
|
||||
- the continuation surface stays aligned with the already-landed primary CTA, queue-control, and queue-recovery posture surfaces without importing dashboard-only retained recommendation analytics
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- shared training types expose a narrow handoff continuation surface
|
||||
- coach-library derivation consumes the already-cached gameplay consumer state rather than adding new runtime fetches
|
||||
- panel-widget callers can fetch the displayed handoff continuation surface directly
|
||||
- session-actor callers can fetch the displayed handoff continuation surface directly
|
||||
- full product build succeeds
|
||||
|
||||
## Validation checklist
|
||||
|
||||
1. build `UnrealHyperTwist.sln` / `UnrealHyperTwistEditor`
|
||||
2. confirm the new continuation surface compiles in shared types and coach library
|
||||
3. confirm panel-widget getters compile and return the derived continuation surface
|
||||
4. confirm session-actor getters compile and return the derived continuation surface
|
||||
5. confirm no backend continuity or dashboard-only handoff analytics work 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 focus/provenance summary surface on `HyperTwistTrainingPanelWidget` and `HyperTwistTrainingSessionActor`, so gameplay callers can render the active coach target and upstream recommendation provenance without reading raw focus ids or source-label strings directly
|
||||
Loading…
Add table
Reference in a new issue