From b9dee5a0ee5f83afebb537c855dd4073041c5b72 Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Mon, 27 Apr 2026 19:19:38 +0200 Subject: [PATCH] Feed explicit recovery actions into coach memory --- .../HyperTwistTrainingRepositoryLibrary.cpp | 54 +++++++++++++++++-- .../HyperTwistTrainingTypes.h | 18 +++++++ 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp index 0db64ac..af33b8c 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp @@ -5209,14 +5209,30 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der 0, 3 ); + const int32 ExplicitFollowUpRecoverySignal = FMath::Clamp( + (QueueExecutionSummary.PromotedFollowUpEventCount * 2) + + QueueExecutionSummary.StartedFollowUpEventCount + + QueueExecutionSummary.CompletedFollowUpEventCount, + 0, + 5 + ); + const int32 ExplicitRecommendedRecoverySignal = FMath::Clamp( + (QueueExecutionSummary.PromotedRecommendedEventCount * 2) + + QueueExecutionSummary.StartedRecommendedEventCount + + QueueExecutionSummary.CompletedRecommendedEventCount, + 0, + 5 + ); const bool bQueueHistoryPrefersFollowUp = DominantDeferredLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp || (DominantCompletedLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp - && QueueExecutionSummary.PromotedEventCount > 0); + && QueueExecutionSummary.PromotedEventCount > 0) + || ExplicitFollowUpRecoverySignal > ExplicitRecommendedRecoverySignal; const bool bQueueHistoryPrefersRecommended = DominantDeferredLane == EHyperTwistTrainingCoachGuidanceLane::Recommended || (DominantCompletedLane == EHyperTwistTrainingCoachGuidanceLane::Recommended - && QueueExecutionSummary.PromotedEventCount > 0); + && QueueExecutionSummary.PromotedEventCount > 0) + || ExplicitRecommendedRecoverySignal > ExplicitFollowUpRecoverySignal; const float PromoteRecoveryActionPressure = (QueueExecutionSummary.bHasOutstandingDeferredWork ? 4.0f : 0.0f) + FMath::Min(static_cast(QueueExecutionSummary.DeferredEventCount) * 0.75f, 3.0f) @@ -5259,14 +5275,14 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der { Snapshot.FollowUpGuidanceContinueBias += FMath::Max( 1, - DeferredRecoverySignal + PromotionRecoverySignal + DeferredRecoverySignal + PromotionRecoverySignal + ExplicitFollowUpRecoverySignal ); } if (bQueueHistoryPrefersRecommended) { Snapshot.RecommendedGuidanceContinueBias += FMath::Max( 1, - DeferredRecoverySignal + PromotionRecoverySignal + DeferredRecoverySignal + PromotionRecoverySignal + ExplicitRecommendedRecoverySignal - (QueueExecutionSummary.bHasBlockedFollowUpFriction ? 1 : 0) ); } @@ -6943,6 +6959,12 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito continue; } + const EHyperTwistTrainingCoachGuidanceLane HistoryEntryLane = + HistoryEntry.bRequiresFollowUp + ? EHyperTwistTrainingCoachGuidanceLane::FollowUp + : HyperTwistTrainingRepositoryLibraryInternal::GuidanceLaneFromQueueSourceLabel( + HistoryEntry.SourceLabel); + switch (HistoryEntry.EventKind) { case EHyperTwistTrainingCoachSessionQueueEventKind::Queued: @@ -6953,6 +6975,14 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito break; case EHyperTwistTrainingCoachSessionQueueEventKind::Started: Summary.StartedEventCount += 1; + if (HistoryEntryLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp) + { + Summary.StartedFollowUpEventCount += 1; + } + else if (HistoryEntryLane == EHyperTwistTrainingCoachGuidanceLane::Recommended) + { + Summary.StartedRecommendedEventCount += 1; + } if (Summary.LastStartedAtUtc.IsEmpty() || HyperTwistTrainingRepositoryLibraryInternal::CompareUtcStrings( HistoryEntry.EventAtUtc, @@ -6980,9 +7010,25 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito break; case EHyperTwistTrainingCoachSessionQueueEventKind::Promoted: Summary.PromotedEventCount += 1; + if (HistoryEntryLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp) + { + Summary.PromotedFollowUpEventCount += 1; + } + else if (HistoryEntryLane == EHyperTwistTrainingCoachGuidanceLane::Recommended) + { + Summary.PromotedRecommendedEventCount += 1; + } break; case EHyperTwistTrainingCoachSessionQueueEventKind::Completed: Summary.CompletedEventCount += 1; + if (HistoryEntryLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp) + { + Summary.CompletedFollowUpEventCount += 1; + } + else if (HistoryEntryLane == EHyperTwistTrainingCoachGuidanceLane::Recommended) + { + Summary.CompletedRecommendedEventCount += 1; + } CompletedCountsByEntryId.FindOrAdd(HistoryEntry.EntryId) += 1; if (Summary.LastCompletedAtUtc.IsEmpty() || HyperTwistTrainingRepositoryLibraryInternal::CompareUtcStrings( diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h index 99dbd4e..9f58cf9 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h @@ -3255,6 +3255,24 @@ struct FHyperTwistTrainingCoachSessionQueueExecutionSummary UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") int32 CompletedEventCount = 0; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 StartedFollowUpEventCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 StartedRecommendedEventCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 PromotedFollowUpEventCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 PromotedRecommendedEventCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 CompletedFollowUpEventCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 CompletedRecommendedEventCount = 0; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") int32 SkippedEventCount = 0;