From ca9e0425bb69a0e4eb5c3c2e75e9262ac7277f7b Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Wed, 29 Apr 2026 17:17:20 +0200 Subject: [PATCH] Learn drill packet recovery outcomes on dashboard --- .../HyperTwistCoachDashboardWidget.cpp | 206 ++++++++++++++++-- .../HyperTwistCoachDashboardWidget.h | 14 ++ 2 files changed, 203 insertions(+), 17 deletions(-) diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp index e93ff45..a2ef14b 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp @@ -360,6 +360,14 @@ namespace HyperTwistCoachDashboardWidgetInternal { return TEXT("accepted weak drill-follow-up-packet recommended handoff history"); } + if (SourceLabel == TEXT("coach-memory-method-drill-follow-up-packet-structure-narrow")) + { + return TEXT("successful narrow drill-follow-up-packet structure history"); + } + if (SourceLabel == TEXT("coach-memory-method-drill-follow-up-packet-structure-broad")) + { + return TEXT("successful broad drill-follow-up-packet redirect history"); + } if (SourceLabel == TEXT("coach-memory-dashboard-queued")) { return TEXT("accepted queued handoff history"); @@ -1283,10 +1291,14 @@ namespace HyperTwistCoachDashboardWidgetInternal for (int32 Index = StartIndex; Index < Entries.Num(); ++Index) { const FHyperTwistCoachDashboardMethodDrillRecoveryMemoryHistoryEntry& Entry = Entries[Index]; + const bool bHasStructureRecoverySignal = + Entry.NarrowMethodDrillPacketStructureRecoveryLaunchCount > 0 + || Entry.BroadMethodDrillPacketStructureRecoveryPromoteCount > 0; if (!Entry.IsStructurallyValid() || Entry.GeneratedGuidancePacketKindLabel.IsEmpty() || (!Entry.bUsedMethodDrillRecoveryMemoryForRecovery - && !Entry.bUsedMethodDrillRecoveryMemoryForHandoff)) + && !Entry.bUsedMethodDrillRecoveryMemoryForHandoff + && !bHasStructureRecoverySignal)) { continue; } @@ -1302,16 +1314,24 @@ namespace HyperTwistCoachDashboardWidgetInternal } HistoryWeight = FMath::Clamp(HistoryWeight, 1, 3); - const bool bStrongPacket = - Entry.bGeneratedPacketUsedStrongRetainedMethodDrillRecoveryPosture - || Entry.bStrongPressureDominant; - const bool bWeakPacket = - Entry.bGeneratedPacketUsedWeakRetainedMethodDrillRecoveryPosture - || Entry.bWeakPressureDominant; - const bool bGenericPacket = - Entry.bGeneratedPacketUsedGenericMethodDrillRecoveryMemory - && !bStrongPacket - && !bWeakPacket; + const bool bStrongPacket = + Entry.bGeneratedPacketUsedStrongRetainedMethodDrillRecoveryPosture + || Entry.bStrongPressureDominant; + const bool bWeakPacket = + Entry.bGeneratedPacketUsedWeakRetainedMethodDrillRecoveryPosture + || Entry.bWeakPressureDominant; + const bool bNarrowStructureRecovery = + Entry.bNarrowPacketStructureRecoveryDominant + || Entry.NarrowMethodDrillPacketStructureRecoveryLaunchReducedCount > 0; + const bool bBroadStructureRecovery = + Entry.bBroadPacketStructureRecoveryDominant + || Entry.BroadMethodDrillPacketStructureRecoveryPromoteReducedCount > 0; + const bool bGenericPacket = + Entry.bGeneratedPacketUsedGenericMethodDrillRecoveryMemory + && !bStrongPacket + && !bWeakPacket + && !bNarrowStructureRecovery + && !bBroadStructureRecovery; if (Entry.GeneratedGuidancePacketKindLabel.Equals(TEXT("queue-entry"), ESearchCase::IgnoreCase)) { @@ -1324,6 +1344,14 @@ namespace HyperTwistCoachDashboardWidgetInternal Bias.bHasStrongContinuationSignal = true; Bias.bHasSignal = true; } + else if (bNarrowStructureRecovery) + { + Bias.StrongQueueEntryCount += HistoryWeight; + Bias.QueueHandoffBias += HistoryWeight * 2; + Bias.LaunchRecoveryBias += HistoryWeight * 2; + Bias.bHasStrongContinuationSignal = true; + Bias.bHasSignal = true; + } else if (bGenericPacket) { Bias.QueueHandoffBias += HistoryWeight; @@ -1345,6 +1373,14 @@ namespace HyperTwistCoachDashboardWidgetInternal Bias.bHasStrongContinuationSignal = true; Bias.bHasSignal = true; } + else if (bNarrowStructureRecovery) + { + Bias.StrongFollowUpPacketCount += HistoryWeight; + Bias.FollowUpHandoffBias += HistoryWeight * 3; + Bias.LaunchRecoveryBias += HistoryWeight * 2; + Bias.bHasStrongContinuationSignal = true; + Bias.bHasSignal = true; + } else if (bGenericPacket) { Bias.FollowUpHandoffBias += HistoryWeight; @@ -1366,6 +1402,14 @@ namespace HyperTwistCoachDashboardWidgetInternal Bias.bHasWeakRedirectSignal = true; Bias.bHasSignal = true; } + else if (bBroadStructureRecovery) + { + Bias.WeakRecommendedBriefCount += HistoryWeight; + Bias.RecommendedHandoffBias += HistoryWeight * 3; + Bias.PromoteRecoveryBias += HistoryWeight * 2; + Bias.bHasWeakRedirectSignal = true; + Bias.bHasSignal = true; + } else if (bGenericPacket) { Bias.RecommendedHandoffBias += HistoryWeight; @@ -1400,7 +1444,10 @@ namespace HyperTwistCoachDashboardWidgetInternal for (int32 Index = 0; Index < Outcomes.Num(); ++Index) { const FHyperTwistCoachDashboardQueueRecoveryOutcome& Outcome = Outcomes[Index]; - if (Outcome.IsStructurallyValid() && Outcome.bUsedMethodDrillHandoffSignal) + if (Outcome.IsStructurallyValid() + && (Outcome.bUsedMethodDrillHandoffSignal + || Outcome.bUsedNarrowMethodDrillPacketStructureRecovery + || Outcome.bUsedBroadMethodDrillPacketStructureRecovery)) { OutIndices.Add(Index); } @@ -1665,6 +1712,12 @@ bool UHyperTwistCoachDashboardWidget::ApplyQueueRecoveryPosture() && MethodDrillRecoveryPacketQueueBias.bHasSignal && MethodDrillRecoveryPacketLaunchBias != HyperTwistCoachDashboardWidgetInternal::EMethodDrillRecoveryMemoryBias::None; + const bool bUseNarrowMethodDrillPacketStructureRecovery = + CachedCoachPanelState.PreferredQueueRecoveryActionSourceLabel + == TEXT("coach-memory-method-drill-follow-up-packet-structure-narrow"); + const bool bUseBroadMethodDrillPacketStructureRecovery = + CachedCoachPanelState.PreferredQueueRecoveryActionSourceLabel + == TEXT("coach-memory-method-drill-follow-up-packet-structure-broad"); auto StartRunAndRefresh = [this](const FHyperTwistTrainingRunState& RunState) { @@ -1685,6 +1738,8 @@ bool UHyperTwistCoachDashboardWidget::ApplyQueueRecoveryPosture() bHasDeferredFirstSuppressionSignal, bPrefersFollowUp, bUseMethodDrillRecoverySignal, + bUseNarrowMethodDrillPacketStructureRecovery, + bUseBroadMethodDrillPacketStructureRecovery, bUseStrongRetainedMethodDrillRecoveryPosture, bUseWeakRetainedMethodDrillRecoveryPosture ]( @@ -1703,6 +1758,12 @@ bool UHyperTwistCoachDashboardWidget::ApplyQueueRecoveryPosture() bBeforeCompletionGap, bHasDeferredFirstSuppressionSignal && bPrefersFollowUp, bUseMethodDrillRecoverySignal, + bUseNarrowMethodDrillPacketStructureRecovery + && ActionKind + == FHyperTwistCoachDashboardQueueRecoveryOutcome::EActionKind::LaunchRecovery, + bUseBroadMethodDrillPacketStructureRecovery + && ActionKind + == FHyperTwistCoachDashboardQueueRecoveryOutcome::EActionKind::PromoteDeferred, bUseStrongRetainedMethodDrillRecoveryPosture && ActionKind == FHyperTwistCoachDashboardQueueRecoveryOutcome::EActionKind::LaunchRecovery, @@ -5828,6 +5889,15 @@ FHyperTwistCoachDashboardQueueRecoveryWeighting UHyperTwistCoachDashboardWidget: ++Weighting.MethodDrillPromoteFailureCount; } } + if (Outcome.bUsedBroadMethodDrillPacketStructureRecovery) + { + ++Weighting.BroadMethodDrillPacketStructurePromoteCount; + Weighting.bHasMethodDrillOutcomeSignal = true; + if (Outcome.bReducedFriction) + { + ++Weighting.BroadMethodDrillPacketStructurePromoteReducedCount; + } + } if (Outcome.bUsedWeakRetainedMethodDrillRecoveryPosture) { ++Weighting.WeakRetainedMethodDrillPromoteCount; @@ -5870,6 +5940,15 @@ FHyperTwistCoachDashboardQueueRecoveryWeighting UHyperTwistCoachDashboardWidget: ++Weighting.MethodDrillLaunchFailureCount; } } + if (Outcome.bUsedNarrowMethodDrillPacketStructureRecovery) + { + ++Weighting.NarrowMethodDrillPacketStructureLaunchCount; + Weighting.bHasMethodDrillOutcomeSignal = true; + if (Outcome.bReducedFriction) + { + ++Weighting.NarrowMethodDrillPacketStructureLaunchReducedCount; + } + } if (Outcome.bUsedStrongRetainedMethodDrillRecoveryPosture) { ++Weighting.StrongRetainedMethodDrillLaunchCount; @@ -6061,10 +6140,25 @@ FHyperTwistCoachDashboardQueueRecoveryWeighting UHyperTwistCoachDashboardWidget: Weighting.WeakRetainedMethodDrillPromoteCount - Weighting.WeakRetainedMethodDrillPromoteReducedCount, 0)) * 0.5f; + const float NarrowMethodDrillPacketStructureLaunchScore = + static_cast(Weighting.NarrowMethodDrillPacketStructureLaunchReducedCount) * 3.0f + + static_cast(FMath::Max( + Weighting.NarrowMethodDrillPacketStructureLaunchCount + - Weighting.NarrowMethodDrillPacketStructureLaunchReducedCount, + 0)) * 0.5f; + const float BroadMethodDrillPacketStructurePromoteScore = + static_cast(Weighting.BroadMethodDrillPacketStructurePromoteReducedCount) * 3.0f + + static_cast(FMath::Max( + Weighting.BroadMethodDrillPacketStructurePromoteCount + - Weighting.BroadMethodDrillPacketStructurePromoteReducedCount, + 0)) * 0.5f; const float AdjustedPromoteScore = PromoteScore + (Weighting.bHasDeferredFirstSignal ? DeferredFirstPromoteScore * 1.5f : 0.0f) + (Weighting.bHasMethodDrillOutcomeSignal ? MethodDrillPromoteOutcomeScore * 1.1f : 0.0f) + + (Weighting.BroadMethodDrillPacketStructurePromoteCount > 0 + ? BroadMethodDrillPacketStructurePromoteScore * 1.2f + : 0.0f) + (Weighting.WeakRetainedMethodDrillPromoteCount > 0 ? WeakRetainedMethodDrillPromoteScore * 1.1f : 0.0f) @@ -6073,6 +6167,9 @@ FHyperTwistCoachDashboardQueueRecoveryWeighting UHyperTwistCoachDashboardWidget: LaunchScore + (Weighting.bHasDeferredFirstSignal ? DeferredFirstLaunchScore * 0.75f : 0.0f) + (Weighting.bHasMethodDrillOutcomeSignal ? MethodDrillLaunchOutcomeScore * 1.1f : 0.0f) + + (Weighting.NarrowMethodDrillPacketStructureLaunchCount > 0 + ? NarrowMethodDrillPacketStructureLaunchScore * 1.2f + : 0.0f) + (Weighting.StrongRetainedMethodDrillLaunchCount > 0 ? StrongRetainedMethodDrillLaunchScore * 1.1f : 0.0f) @@ -6412,6 +6509,8 @@ void UHyperTwistCoachDashboardWidget::RecordQueueRecoveryOutcome( const bool bBeforeCompletionGap, const bool bUsedDeferredFirstSuppressionSignal, const bool bUsedMethodDrillHandoffSignal, + const bool bUsedNarrowMethodDrillPacketStructureRecovery, + const bool bUsedBroadMethodDrillPacketStructureRecovery, const bool bUsedStrongRetainedMethodDrillRecoveryPosture, const bool bUsedWeakRetainedMethodDrillRecoveryPosture, const bool bSucceeded) @@ -6450,6 +6549,10 @@ void UHyperTwistCoachDashboardWidget::RecordQueueRecoveryOutcome( bUsedDeferredFirstSuppressionSignal; QueueRecoveryOutcome.bUsedMethodDrillHandoffSignal = bUsedMethodDrillHandoffSignal; + QueueRecoveryOutcome.bUsedNarrowMethodDrillPacketStructureRecovery = + bUsedNarrowMethodDrillPacketStructureRecovery; + QueueRecoveryOutcome.bUsedBroadMethodDrillPacketStructureRecovery = + bUsedBroadMethodDrillPacketStructureRecovery; QueueRecoveryOutcome.bUsedStrongRetainedMethodDrillRecoveryPosture = bUsedStrongRetainedMethodDrillRecoveryPosture; QueueRecoveryOutcome.bUsedWeakRetainedMethodDrillRecoveryPosture = @@ -6815,10 +6918,18 @@ void UHyperTwistCoachDashboardWidget::RecordMethodDrillRecoveryMemoryHistorySnap == TEXT("coach-memory-method-drill-recovery-strong") || CachedCoachPanelState.PreferredQueueRecoveryActionSourceLabel == TEXT("coach-memory-method-drill-recovery-weak"); + const bool bPacketStructureRecoverySourceActive = + CachedCoachPanelState.PreferredQueueRecoveryActionSourceLabel + == TEXT("coach-memory-method-drill-follow-up-packet-structure-narrow") + || CachedCoachPanelState.PreferredQueueRecoveryActionSourceLabel + == TEXT("coach-memory-method-drill-follow-up-packet-structure-broad"); if (!bHasMethodDrillRecoveryHistory && !QueueRecoveryWeighting.bHasMethodDrillMemorySignal && !bUsedMethodDrillRecoveryMemoryForHandoff - && !bDrillRecoverySourceActive) + && !bDrillRecoverySourceActive + && !bPacketStructureRecoverySourceActive + && QueueRecoveryWeighting.NarrowMethodDrillPacketStructureLaunchCount <= 0 + && QueueRecoveryWeighting.BroadMethodDrillPacketStructurePromoteCount <= 0) { return; } @@ -6840,6 +6951,14 @@ void UHyperTwistCoachDashboardWidget::RecordMethodDrillRecoveryMemoryHistorySnap CachedCoachPanelState.WeakMethodDrillRecoveryHistoryCount; Entry.MethodDrillRecoveryAverageOutcomeScore = CachedCoachPanelState.MethodDrillRecoveryAverageOutcomeScore; + Entry.NarrowMethodDrillPacketStructureRecoveryLaunchCount = + QueueRecoveryWeighting.NarrowMethodDrillPacketStructureLaunchCount; + Entry.NarrowMethodDrillPacketStructureRecoveryLaunchReducedCount = + QueueRecoveryWeighting.NarrowMethodDrillPacketStructureLaunchReducedCount; + Entry.BroadMethodDrillPacketStructureRecoveryPromoteCount = + QueueRecoveryWeighting.BroadMethodDrillPacketStructurePromoteCount; + Entry.BroadMethodDrillPacketStructureRecoveryPromoteReducedCount = + QueueRecoveryWeighting.BroadMethodDrillPacketStructurePromoteReducedCount; Entry.bStrongPressureDominant = Entry.MethodDrillRecoveryHistoryCount >= 2 && Entry.StrongMethodDrillRecoveryHistoryCount @@ -6850,6 +6969,18 @@ void UHyperTwistCoachDashboardWidget::RecordMethodDrillRecoveryMemoryHistorySnap && Entry.WeakMethodDrillRecoveryHistoryCount > Entry.StrongMethodDrillRecoveryHistoryCount && Entry.MethodDrillRecoveryAverageOutcomeScore <= 45.0f; + Entry.bNarrowPacketStructureRecoveryDominant = + Entry.NarrowMethodDrillPacketStructureRecoveryLaunchCount > 0 + && Entry.NarrowMethodDrillPacketStructureRecoveryLaunchReducedCount * 2 + >= Entry.NarrowMethodDrillPacketStructureRecoveryLaunchCount + && Entry.NarrowMethodDrillPacketStructureRecoveryLaunchCount + >= Entry.BroadMethodDrillPacketStructureRecoveryPromoteCount; + Entry.bBroadPacketStructureRecoveryDominant = + Entry.BroadMethodDrillPacketStructureRecoveryPromoteCount > 0 + && Entry.BroadMethodDrillPacketStructureRecoveryPromoteReducedCount * 2 + >= Entry.BroadMethodDrillPacketStructureRecoveryPromoteCount + && Entry.BroadMethodDrillPacketStructureRecoveryPromoteCount + >= Entry.NarrowMethodDrillPacketStructureRecoveryLaunchCount; Entry.bUsedMethodDrillRecoveryMemoryForRecovery = QueueRecoveryWeighting.bHasMethodDrillMemorySignal; Entry.bUsedMethodDrillRecoveryMemoryForHandoff = @@ -6982,6 +7113,14 @@ void UHyperTwistCoachDashboardWidget::RecordMethodDrillRecoveryMemoryHistorySnap == Entry.StrongMethodDrillRecoveryHistoryCount && MethodDrillRecoveryMemoryHistoryEntries.Last().WeakMethodDrillRecoveryHistoryCount == Entry.WeakMethodDrillRecoveryHistoryCount + && MethodDrillRecoveryMemoryHistoryEntries.Last().NarrowMethodDrillPacketStructureRecoveryLaunchCount + == Entry.NarrowMethodDrillPacketStructureRecoveryLaunchCount + && MethodDrillRecoveryMemoryHistoryEntries.Last().NarrowMethodDrillPacketStructureRecoveryLaunchReducedCount + == Entry.NarrowMethodDrillPacketStructureRecoveryLaunchReducedCount + && MethodDrillRecoveryMemoryHistoryEntries.Last().BroadMethodDrillPacketStructureRecoveryPromoteCount + == Entry.BroadMethodDrillPacketStructureRecoveryPromoteCount + && MethodDrillRecoveryMemoryHistoryEntries.Last().BroadMethodDrillPacketStructureRecoveryPromoteReducedCount + == Entry.BroadMethodDrillPacketStructureRecoveryPromoteReducedCount && FMath::IsNearlyEqual( MethodDrillRecoveryMemoryHistoryEntries.Last().MethodDrillRecoveryAverageOutcomeScore, Entry.MethodDrillRecoveryAverageOutcomeScore) @@ -6989,6 +7128,10 @@ void UHyperTwistCoachDashboardWidget::RecordMethodDrillRecoveryMemoryHistorySnap == Entry.bStrongPressureDominant && MethodDrillRecoveryMemoryHistoryEntries.Last().bWeakPressureDominant == Entry.bWeakPressureDominant + && MethodDrillRecoveryMemoryHistoryEntries.Last().bNarrowPacketStructureRecoveryDominant + == Entry.bNarrowPacketStructureRecoveryDominant + && MethodDrillRecoveryMemoryHistoryEntries.Last().bBroadPacketStructureRecoveryDominant + == Entry.bBroadPacketStructureRecoveryDominant && MethodDrillRecoveryMemoryHistoryEntries.Last().GeneratedGuidancePacketKindLabel == Entry.GeneratedGuidancePacketKindLabel && MethodDrillRecoveryMemoryHistoryEntries.Last().GeneratedGuidancePacketSourceLabel @@ -8970,7 +9113,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() const FString QueueRecoveryOutcomeDetailLine = !bHasQueueRecoveryOutcome || !QueueRecoveryOutcome.IsStructurallyValid() ? TEXT("Outcome detail: apply a queue-recovery action to compare before/after pressure, deferred count, blocked follow-up state, and completion-gap state.") : FString::Printf( - TEXT("Recorded: %s | Pressure %.2f -> %.2f | Deferred %d -> %d | Blocked follow-up %s -> %s | Outstanding deferred %s -> %s | Completion gap %s -> %s | deferred-first weighted: %s | drill-weighted: %s | retained posture: %s"), + TEXT("Recorded: %s | Pressure %.2f -> %.2f | Deferred %d -> %d | Blocked follow-up %s -> %s | Outstanding deferred %s -> %s | Completion gap %s -> %s | deferred-first weighted: %s | drill-weighted: %s | packet-structure recovery: %s | retained posture: %s"), *QueueRecoveryOutcome.RecordedAtUtc, QueueRecoveryOutcome.BeforePressureScore, QueueRecoveryOutcome.AfterPressureScore, @@ -8984,6 +9127,11 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() QueueRecoveryOutcome.bAfterCompletionGap ? TEXT("yes") : TEXT("no"), QueueRecoveryOutcome.bUsedDeferredFirstSuppressionSignal ? TEXT("yes") : TEXT("no"), QueueRecoveryOutcome.bUsedMethodDrillHandoffSignal ? TEXT("yes") : TEXT("no"), + QueueRecoveryOutcome.bUsedNarrowMethodDrillPacketStructureRecovery + ? TEXT("narrow continuation") + : (QueueRecoveryOutcome.bUsedBroadMethodDrillPacketStructureRecovery + ? TEXT("broad redirect") + : TEXT("none")), *HyperTwistCoachDashboardWidgetInternal::DescribeRetainedMethodDrillRecoveryPosture( QueueRecoveryOutcome.bUsedStrongRetainedMethodDrillRecoveryPosture, QueueRecoveryOutcome.bUsedWeakRetainedMethodDrillRecoveryPosture) @@ -9020,12 +9168,17 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() && SelectedMethodDrillRecoveryOutcome->IsStructurallyValid() && SelectedMethodDrillRecoveryHistoryPosition != INDEX_NONE ? FString::Printf( - TEXT("Drill recovery history: %d entries | selected %d/%d | %s | %s | Stance: %s | Recorded: %s"), + TEXT("Drill recovery history: %d entries | selected %d/%d | %s | %s | Packet recovery: %s | Stance: %s | Recorded: %s"), MethodDrillRecoveryHistoryIndices.Num(), SelectedMethodDrillRecoveryHistoryPosition + 1, MethodDrillRecoveryHistoryIndices.Num(), *SelectedMethodDrillRecoveryOutcome->AppliedActionLabel, *MethodDrillRecoveryHistoryVerdictLine, + SelectedMethodDrillRecoveryOutcome->bUsedNarrowMethodDrillPacketStructureRecovery + ? TEXT("narrow continuation") + : (SelectedMethodDrillRecoveryOutcome->bUsedBroadMethodDrillPacketStructureRecovery + ? TEXT("broad redirect") + : TEXT("none")), *HyperTwistCoachDashboardWidgetInternal::DescribeRetainedMethodDrillRecoveryPosture( SelectedMethodDrillRecoveryOutcome->bUsedStrongRetainedMethodDrillRecoveryPosture, SelectedMethodDrillRecoveryOutcome->bUsedWeakRetainedMethodDrillRecoveryPosture), @@ -9035,7 +9188,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() SelectedMethodDrillRecoveryOutcome != nullptr && SelectedMethodDrillRecoveryOutcome->IsStructurallyValid() ? FString::Printf( - TEXT("Source: %s | Pressure %.2f -> %.2f | Deferred %d -> %d | Blocked follow-up %s -> %s | Outstanding deferred %s -> %s | Completion gap %s -> %s | deferred-first weighted: %s | retained posture: %s"), + TEXT("Source: %s | Pressure %.2f -> %.2f | Deferred %d -> %d | Blocked follow-up %s -> %s | Outstanding deferred %s -> %s | Completion gap %s -> %s | deferred-first weighted: %s | packet-structure recovery: %s | retained posture: %s"), *MethodDrillRecoveryHistorySourceLine, SelectedMethodDrillRecoveryOutcome->BeforePressureScore, SelectedMethodDrillRecoveryOutcome->AfterPressureScore, @@ -9048,6 +9201,11 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() SelectedMethodDrillRecoveryOutcome->bBeforeCompletionGap ? TEXT("yes") : TEXT("no"), SelectedMethodDrillRecoveryOutcome->bAfterCompletionGap ? TEXT("yes") : TEXT("no"), SelectedMethodDrillRecoveryOutcome->bUsedDeferredFirstSuppressionSignal ? TEXT("yes") : TEXT("no"), + SelectedMethodDrillRecoveryOutcome->bUsedNarrowMethodDrillPacketStructureRecovery + ? TEXT("narrow continuation") + : (SelectedMethodDrillRecoveryOutcome->bUsedBroadMethodDrillPacketStructureRecovery + ? TEXT("broad redirect") + : TEXT("none")), *HyperTwistCoachDashboardWidgetInternal::DescribeRetainedMethodDrillRecoveryPosture( SelectedMethodDrillRecoveryOutcome->bUsedStrongRetainedMethodDrillRecoveryPosture, SelectedMethodDrillRecoveryOutcome->bUsedWeakRetainedMethodDrillRecoveryPosture)) @@ -9140,13 +9298,27 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() SelectedMethodDrillRecoveryMemoryHistoryEntry != nullptr && SelectedMethodDrillRecoveryMemoryHistoryEntry->IsStructurallyValid() ? FString::Printf( - TEXT("Source: %s | Strong/weak/history %d/%d/%d avg %.1f | Dominant pressure: %s | Stance: %s | Recovery memory tipped: %s | Handoff memory tipped: %s | Packet kind: %s | Packet source: %s | Packet headline: %s | Packet action: %s | Packet focus %d | Packet stance: %s | Recovery posture: %s | Handoff posture: %s"), + TEXT("Source: %s | Strong/weak/history %d/%d/%d avg %.1f | Structure recovery narrow %d/%d broad %d/%d | Dominant pressure: %s | Structure bias: %s | Stance: %s | Recovery memory tipped: %s | Handoff memory tipped: %s | Packet kind: %s | Packet source: %s | Packet headline: %s | Packet action: %s | Packet focus %d | Packet stance: %s | Recovery posture: %s | Handoff posture: %s"), *MethodDrillRecoveryMemorySourceLine, SelectedMethodDrillRecoveryMemoryHistoryEntry->StrongMethodDrillRecoveryHistoryCount, SelectedMethodDrillRecoveryMemoryHistoryEntry->WeakMethodDrillRecoveryHistoryCount, SelectedMethodDrillRecoveryMemoryHistoryEntry->MethodDrillRecoveryHistoryCount, SelectedMethodDrillRecoveryMemoryHistoryEntry->MethodDrillRecoveryAverageOutcomeScore, + SelectedMethodDrillRecoveryMemoryHistoryEntry + ->NarrowMethodDrillPacketStructureRecoveryLaunchCount, + SelectedMethodDrillRecoveryMemoryHistoryEntry + ->NarrowMethodDrillPacketStructureRecoveryLaunchReducedCount, + SelectedMethodDrillRecoveryMemoryHistoryEntry + ->BroadMethodDrillPacketStructureRecoveryPromoteCount, + SelectedMethodDrillRecoveryMemoryHistoryEntry + ->BroadMethodDrillPacketStructureRecoveryPromoteReducedCount, *MethodDrillRecoveryMemoryDominantPressureLine, + SelectedMethodDrillRecoveryMemoryHistoryEntry->bNarrowPacketStructureRecoveryDominant + ? TEXT("narrow continuation") + : (SelectedMethodDrillRecoveryMemoryHistoryEntry + ->bBroadPacketStructureRecoveryDominant + ? TEXT("broad redirect") + : TEXT("none")), *HyperTwistCoachDashboardWidgetInternal::DescribeMethodDrillRecoveryMemoryBias( SelectedMethodDrillRecoveryMemoryHistoryBias), SelectedMethodDrillRecoveryMemoryHistoryEntry->bUsedMethodDrillRecoveryMemoryForRecovery diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h index f887001..7b4c2f2 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h @@ -149,6 +149,8 @@ struct FHyperTwistCoachDashboardQueueRecoveryOutcome bool bShiftedFriction = false; bool bUsedDeferredFirstSuppressionSignal = false; bool bUsedMethodDrillHandoffSignal = false; + bool bUsedNarrowMethodDrillPacketStructureRecovery = false; + bool bUsedBroadMethodDrillPacketStructureRecovery = false; bool bUsedStrongRetainedMethodDrillRecoveryPosture = false; bool bUsedWeakRetainedMethodDrillRecoveryPosture = false; @@ -176,6 +178,10 @@ struct FHyperTwistCoachDashboardQueueRecoveryWeighting int32 MethodDrillLaunchCount = 0; int32 MethodDrillLaunchReducedCount = 0; int32 MethodDrillLaunchFailureCount = 0; + int32 NarrowMethodDrillPacketStructureLaunchCount = 0; + int32 NarrowMethodDrillPacketStructureLaunchReducedCount = 0; + int32 BroadMethodDrillPacketStructurePromoteCount = 0; + int32 BroadMethodDrillPacketStructurePromoteReducedCount = 0; int32 StrongRetainedMethodDrillLaunchCount = 0; int32 StrongRetainedMethodDrillLaunchReducedCount = 0; int32 WeakRetainedMethodDrillPromoteCount = 0; @@ -350,9 +356,15 @@ struct FHyperTwistCoachDashboardMethodDrillRecoveryMemoryHistoryEntry int32 MethodDrillRecoveryHistoryCount = 0; int32 StrongMethodDrillRecoveryHistoryCount = 0; int32 WeakMethodDrillRecoveryHistoryCount = 0; + int32 NarrowMethodDrillPacketStructureRecoveryLaunchCount = 0; + int32 NarrowMethodDrillPacketStructureRecoveryLaunchReducedCount = 0; + int32 BroadMethodDrillPacketStructureRecoveryPromoteCount = 0; + int32 BroadMethodDrillPacketStructureRecoveryPromoteReducedCount = 0; float MethodDrillRecoveryAverageOutcomeScore = 0.0f; bool bStrongPressureDominant = false; bool bWeakPressureDominant = false; + bool bNarrowPacketStructureRecoveryDominant = false; + bool bBroadPacketStructureRecoveryDominant = false; bool bGeneratedPacketUsedStrongRetainedMethodDrillRecoveryPosture = false; bool bGeneratedPacketUsedWeakRetainedMethodDrillRecoveryPosture = false; bool bGeneratedPacketUsedGenericMethodDrillRecoveryMemory = false; @@ -1393,6 +1405,8 @@ private: bool bBeforeCompletionGap, bool bUsedDeferredFirstSuppressionSignal, bool bUsedMethodDrillHandoffSignal, + bool bUsedNarrowMethodDrillPacketStructureRecovery, + bool bUsedBroadMethodDrillPacketStructureRecovery, bool bUsedStrongRetainedMethodDrillRecoveryPosture, bool bUsedWeakRetainedMethodDrillRecoveryPosture, bool bSucceeded