Explain launch budget memory in coaching
This commit is contained in:
parent
377b57954d
commit
620b3a1129
5 changed files with 259 additions and 4 deletions
|
|
@ -129,10 +129,32 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
{
|
||||
return TEXT("balanced queue-recovery history");
|
||||
}
|
||||
if (SourceLabel == TEXT("recommendation-history-broadened-launch"))
|
||||
{
|
||||
return TEXT("successful broadened-launch history");
|
||||
}
|
||||
if (SourceLabel == TEXT("recommendation-history-tightened-launch"))
|
||||
{
|
||||
return TEXT("successful tightened-launch history");
|
||||
}
|
||||
|
||||
return SourceLabel.IsEmpty() ? TEXT("n/a") : SourceLabel;
|
||||
}
|
||||
|
||||
FString DescribeLaunchBudgetBias(const int32 Bias)
|
||||
{
|
||||
if (Bias > 0)
|
||||
{
|
||||
return TEXT("broaden");
|
||||
}
|
||||
if (Bias < 0)
|
||||
{
|
||||
return TEXT("tighten");
|
||||
}
|
||||
|
||||
return TEXT("steady");
|
||||
}
|
||||
|
||||
UTextBlock* AddTextRow(
|
||||
UWidgetTree* WidgetTree,
|
||||
UVerticalBox* Parent,
|
||||
|
|
@ -4964,7 +4986,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
}
|
||||
|
||||
CoachHandoffRecommendationDetailLine = FString::Printf(
|
||||
TEXT("Closure continuation bias %d | Closure suppression bias %d | Queue ready: %s | Follow-up ready: %s | Recommended ready: %s | Preferred lane: %s | Memory source: %s%s%s | Handoff history preferred: %s | accepted q/f/r %d/%d/%d | recommended q/f/r %d/%d/%d"),
|
||||
TEXT("Closure continuation bias %d | Closure suppression bias %d | Queue ready: %s | Follow-up ready: %s | Recommended ready: %s | Preferred lane: %s | Memory source: %s%s%s | Launch bias: %s from %s | broadened/tightened history %d/%d | Handoff history preferred: %s | accepted q/f/r %d/%d/%d | recommended q/f/r %d/%d/%d"),
|
||||
HandoffClosureBias.ContinuationBias,
|
||||
HandoffClosureBias.SuppressionBias,
|
||||
bQueueReadyForHandoff ? TEXT("yes") : TEXT("no"),
|
||||
|
|
@ -4979,6 +5001,12 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
bHandoffRecommendationUsedHistory
|
||||
? TEXT(" | Retained handoff history actively weighted this recommendation.")
|
||||
: TEXT(""),
|
||||
*HyperTwistCoachDashboardWidgetInternal::DescribeLaunchBudgetBias(
|
||||
CachedCoachPanelState.PreferredLaunchBudgetBias),
|
||||
*HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
|
||||
CachedCoachPanelState.PreferredLaunchBudgetSourceLabel),
|
||||
CachedCoachPanelState.BroadenedLaunchBudgetHistoryCount,
|
||||
CachedCoachPanelState.TightenedLaunchBudgetHistoryCount,
|
||||
*HyperTwistCoachDashboardWidgetInternal::DescribeHandoffRecommendationKind(
|
||||
HandoffHistoryBias.PreferredKind),
|
||||
HandoffHistoryBias.QueueAcceptedDeltaCount,
|
||||
|
|
@ -5170,7 +5198,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
const FString GuidancePreferenceDetailLine =
|
||||
GuidanceLanePreference.IsStructurallyValid()
|
||||
? FString::Printf(
|
||||
TEXT("Recommended lane: %d decisions | Continue bias %d | Avg success %.2f | Closure suppress bias %d || Follow-up lane: %d decisions | Continue bias %d | Avg success %.2f | Closure continuation bias %d | The dashboard adopts this preferred lane whenever it needs to surface the next guidance preview."),
|
||||
TEXT("Recommended lane: %d decisions | Continue bias %d | Avg success %.2f | Closure suppress bias %d || Follow-up lane: %d decisions | Continue bias %d | Avg success %.2f | Closure continuation bias %d | Launch bias: %s from %s | broadened/tightened history %d/%d | The dashboard adopts this preferred lane whenever it needs to surface the next guidance preview."),
|
||||
GuidanceLanePreference.RecommendedDecisionCount,
|
||||
GuidanceLanePreference.RecommendedContinueBias,
|
||||
GuidanceLanePreference.RecommendedAverageSuccessRate,
|
||||
|
|
@ -5178,7 +5206,13 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
GuidanceLanePreference.FollowUpDecisionCount,
|
||||
GuidanceLanePreference.FollowUpContinueBias,
|
||||
GuidanceLanePreference.FollowUpAverageSuccessRate,
|
||||
GuidanceLanePreference.ClosureContinuationBias
|
||||
GuidanceLanePreference.ClosureContinuationBias,
|
||||
*HyperTwistCoachDashboardWidgetInternal::DescribeLaunchBudgetBias(
|
||||
CachedCoachPanelState.PreferredLaunchBudgetBias),
|
||||
*HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
|
||||
CachedCoachPanelState.PreferredLaunchBudgetSourceLabel),
|
||||
CachedCoachPanelState.BroadenedLaunchBudgetHistoryCount,
|
||||
CachedCoachPanelState.TightenedLaunchBudgetHistoryCount
|
||||
)
|
||||
: TEXT("Preference detail: build recommended or follow-up guidance to let the dashboard choose a next surfaced lane.");
|
||||
const bool bQueueRecoveryMemorySource =
|
||||
|
|
@ -5510,7 +5544,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
const FString GuidanceRationaleDetailLine =
|
||||
ActivePreviewBrief != nullptr
|
||||
? FString::Printf(
|
||||
TEXT("Brief: %s | Action: %s | Deck: %s | Method: %s | Focus cases: %d | Review: %s | Cadence: %s | Variety: %s | Guidance source: %s | Selected focus: %s | Matching signals: %d | Case signal: %s | Top signals: %s"),
|
||||
TEXT("Brief: %s | Action: %s | Deck: %s | Method: %s | Focus cases: %d | Review: %s | Cadence: %s | Variety: %s | Guidance source: %s | Launch bias: %s from %s | broadened/tightened history %d/%d | Selected focus: %s | Matching signals: %d | Case signal: %s | Top signals: %s"),
|
||||
ActivePreviewBrief->Headline.IsEmpty() ? TEXT("n/a") : *ActivePreviewBrief->Headline,
|
||||
ActivePreviewBrief->PrimaryActionLabel.IsEmpty() ? TEXT("n/a") : *ActivePreviewBrief->PrimaryActionLabel,
|
||||
ActivePreviewBrief->FocusDeckId.IsEmpty() ? TEXT("n/a") : *ActivePreviewBrief->FocusDeckId,
|
||||
|
|
@ -5521,6 +5555,12 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
ActivePreviewBrief->bNeedsVarietyRotation ? TEXT("yes") : TEXT("no"),
|
||||
*HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel),
|
||||
*HyperTwistCoachDashboardWidgetInternal::DescribeLaunchBudgetBias(
|
||||
CachedCoachPanelState.PreferredLaunchBudgetBias),
|
||||
*HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
|
||||
CachedCoachPanelState.PreferredLaunchBudgetSourceLabel),
|
||||
CachedCoachPanelState.BroadenedLaunchBudgetHistoryCount,
|
||||
CachedCoachPanelState.TightenedLaunchBudgetHistoryCount,
|
||||
bSelectedPreviewCaseIsExplicitFocus ? TEXT("yes") : TEXT("no"),
|
||||
SelectedPreviewCaseSignalCount,
|
||||
*SelectedPreviewCaseSignalLine,
|
||||
|
|
|
|||
|
|
@ -82,6 +82,14 @@ namespace HyperTwistTrainingCoachLibraryInternal
|
|||
{
|
||||
return TEXT("balanced queue-recovery history");
|
||||
}
|
||||
if (SourceLabel == TEXT("recommendation-history-broadened-launch"))
|
||||
{
|
||||
return TEXT("successful broadened-launch history");
|
||||
}
|
||||
if (SourceLabel == TEXT("recommendation-history-tightened-launch"))
|
||||
{
|
||||
return TEXT("successful tightened-launch history");
|
||||
}
|
||||
|
||||
return SourceLabel.IsEmpty() ? TEXT("none") : SourceLabel;
|
||||
}
|
||||
|
|
@ -1790,6 +1798,169 @@ FHyperTwistCoachBrief UHyperTwistTrainingCoachLibrary::RefineCoachBriefWithClosu
|
|||
return Brief;
|
||||
}
|
||||
|
||||
FHyperTwistCoachSignal UHyperTwistTrainingCoachLibrary::DeriveLaunchBudgetHistorySignal(
|
||||
const FHyperTwistTrainingCoachMemorySnapshot& CoachMemorySnapshot,
|
||||
const FHyperTwistCoachBrief& CurrentBrief)
|
||||
{
|
||||
if (CoachMemorySnapshot.PreferredLaunchBudgetBias == 0
|
||||
|| (CoachMemorySnapshot.BroadenedLaunchBudgetHistoryCount <= 0
|
||||
&& CoachMemorySnapshot.TightenedLaunchBudgetHistoryCount <= 0))
|
||||
{
|
||||
return FHyperTwistCoachSignal();
|
||||
}
|
||||
|
||||
const bool bBroadenPreferred = CoachMemorySnapshot.PreferredLaunchBudgetBias > 0;
|
||||
const bool bCompetingGuidancePressure =
|
||||
CoachMemorySnapshot.RecommendedGuidanceContinueBias > 0
|
||||
&& CoachMemorySnapshot.FollowUpGuidanceContinueBias > 0;
|
||||
const float Score = FMath::Clamp(
|
||||
58.0f
|
||||
+ static_cast<float>(FMath::Max(
|
||||
CoachMemorySnapshot.BroadenedLaunchBudgetHistoryCount,
|
||||
CoachMemorySnapshot.TightenedLaunchBudgetHistoryCount)) * 4.0f
|
||||
+ (bCompetingGuidancePressure ? 4.0f : 0.0f)
|
||||
+ ((CurrentBrief.FocusLane == EHyperTwistCoachFocusLane::Cadence
|
||||
|| CurrentBrief.FocusLane == EHyperTwistCoachFocusLane::Stability
|
||||
|| CurrentBrief.FocusLane == EHyperTwistCoachFocusLane::ReviewBacklog) ? 3.0f : 0.0f),
|
||||
0.0f,
|
||||
100.0f
|
||||
);
|
||||
const FString SignalId = bBroadenPreferred
|
||||
? TEXT("launch_budget_history_broaden")
|
||||
: TEXT("launch_budget_history_tighten");
|
||||
const EHyperTwistCoachFocusLane FocusLane = bBroadenPreferred
|
||||
? EHyperTwistCoachFocusLane::ReviewBacklog
|
||||
: EHyperTwistCoachFocusLane::Stability;
|
||||
const FString Headline = bBroadenPreferred
|
||||
? TEXT("Launch history favors a broader next coach run")
|
||||
: TEXT("Launch history favors a tighter next coach run");
|
||||
const FString PreferredGuidanceLaneLabel =
|
||||
CoachMemorySnapshot.PreferredGuidanceLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp
|
||||
? TEXT("follow-up")
|
||||
: (CoachMemorySnapshot.PreferredGuidanceLane == EHyperTwistTrainingCoachGuidanceLane::Recommended
|
||||
? TEXT("recommended")
|
||||
: TEXT("none"));
|
||||
const FString Detail = FString::Printf(
|
||||
TEXT("launchBias=%s, broadenedHistory=%d, tightenedHistory=%d, guidanceLane=%s, handoff=%s, source=%s"),
|
||||
bBroadenPreferred ? TEXT("broaden") : TEXT("tighten"),
|
||||
CoachMemorySnapshot.BroadenedLaunchBudgetHistoryCount,
|
||||
CoachMemorySnapshot.TightenedLaunchBudgetHistoryCount,
|
||||
*PreferredGuidanceLaneLabel,
|
||||
*HyperTwistTrainingCoachLibraryInternal::DescribeCoachHandoffKind(
|
||||
CoachMemorySnapshot.PreferredCoachHandoffKind),
|
||||
CoachMemorySnapshot.PreferredLaunchBudgetSourceLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: *HyperTwistTrainingCoachLibraryInternal::DescribeCoachMemorySourceLabel(
|
||||
CoachMemorySnapshot.PreferredLaunchBudgetSourceLabel)
|
||||
);
|
||||
const EHyperTwistTrainingDeliveryMode SuggestedMode =
|
||||
CurrentBrief.SuggestedMode != EHyperTwistTrainingDeliveryMode::Timer
|
||||
? CurrentBrief.SuggestedMode
|
||||
: CoachMemorySnapshot.DominantCoachSuggestedMode;
|
||||
const EHyperTwistTrainingSelectionPolicy SuggestedSelectionPolicy =
|
||||
CurrentBrief.SuggestedSelectionPolicy != EHyperTwistTrainingSelectionPolicy::Weighted
|
||||
? CurrentBrief.SuggestedSelectionPolicy
|
||||
: CoachMemorySnapshot.DominantCoachSelectionPolicy;
|
||||
|
||||
FHyperTwistCoachSignal Signal = HyperTwistTrainingCoachLibraryInternal::MakeSignal(
|
||||
SignalId,
|
||||
FocusLane,
|
||||
Score,
|
||||
Headline,
|
||||
Detail,
|
||||
SuggestedMode,
|
||||
SuggestedSelectionPolicy
|
||||
);
|
||||
Signal.SuggestedDeckId = !CurrentBrief.FocusDeckId.IsEmpty()
|
||||
? CurrentBrief.FocusDeckId
|
||||
: CoachMemorySnapshot.FocusDeckId;
|
||||
Signal.SuggestedMethodSegmentId = !CurrentBrief.FocusMethodSegmentId.IsEmpty()
|
||||
? CurrentBrief.FocusMethodSegmentId
|
||||
: CoachMemorySnapshot.FocusMethodSegmentId;
|
||||
Signal.SuggestedCaseIds = CurrentBrief.FocusCaseIds.Num() > 0
|
||||
? CurrentBrief.FocusCaseIds
|
||||
: (CoachMemorySnapshot.WeakCaseIds.Num() > 0
|
||||
? CoachMemorySnapshot.WeakCaseIds
|
||||
: CoachMemorySnapshot.DueCaseIds);
|
||||
HyperTwistTrainingCoachLibraryInternal::ApplyGuidancePreferenceToSignal(
|
||||
Signal,
|
||||
CoachMemorySnapshot.PreferredGuidanceLane,
|
||||
CoachMemorySnapshot,
|
||||
bCompetingGuidancePressure
|
||||
);
|
||||
return Signal;
|
||||
}
|
||||
|
||||
FHyperTwistCoachBrief UHyperTwistTrainingCoachLibrary::RefineCoachBriefWithLaunchBudgetHistorySignal(
|
||||
const FHyperTwistCoachBrief& BaseBrief,
|
||||
const FHyperTwistCoachSignal& LaunchBudgetHistorySignal)
|
||||
{
|
||||
if (LaunchBudgetHistorySignal.SignalId.IsEmpty())
|
||||
{
|
||||
return BaseBrief;
|
||||
}
|
||||
|
||||
FHyperTwistCoachBrief Brief = BaseBrief;
|
||||
if (!Brief.Signals.ContainsByPredicate(
|
||||
[&LaunchBudgetHistorySignal](const FHyperTwistCoachSignal& Candidate)
|
||||
{
|
||||
return Candidate.SignalId == LaunchBudgetHistorySignal.SignalId;
|
||||
}))
|
||||
{
|
||||
Brief.Signals.Add(LaunchBudgetHistorySignal);
|
||||
}
|
||||
HyperTwistTrainingCoachLibraryInternal::SortSignals(Brief.Signals);
|
||||
|
||||
const bool bLaunchFacingBrief =
|
||||
Brief.FocusLane == EHyperTwistCoachFocusLane::ReviewBacklog
|
||||
|| Brief.FocusLane == EHyperTwistCoachFocusLane::Cadence
|
||||
|| Brief.FocusLane == EHyperTwistCoachFocusLane::Stability
|
||||
|| Brief.bNeedsCadenceRecovery;
|
||||
const bool bShouldPromoteLaunchSignal =
|
||||
bLaunchFacingBrief
|
||||
&& LaunchBudgetHistorySignal.Score >= Brief.PriorityScore - 4.0f;
|
||||
if (bShouldPromoteLaunchSignal)
|
||||
{
|
||||
for (FHyperTwistCoachSignal& Signal : Brief.Signals)
|
||||
{
|
||||
if (Signal.SignalId == LaunchBudgetHistorySignal.SignalId)
|
||||
{
|
||||
Signal.Score = FMath::Clamp(
|
||||
FMath::Max(Signal.Score, Brief.Signals[0].Score + 0.5f),
|
||||
0.0f,
|
||||
100.0f
|
||||
);
|
||||
Signal.Priority = HyperTwistTrainingCoachLibraryInternal::PriorityFromScore(Signal.Score);
|
||||
Signal.bNeedsImmediateAttention = Signal.Priority == EHyperTwistCoachPriority::Critical;
|
||||
break;
|
||||
}
|
||||
}
|
||||
HyperTwistTrainingCoachLibraryInternal::SortSignals(Brief.Signals);
|
||||
}
|
||||
|
||||
if (Brief.Signals.Num() > 0)
|
||||
{
|
||||
const FString OriginalDeckId = Brief.FocusDeckId;
|
||||
const FString OriginalMethodSegmentId = Brief.FocusMethodSegmentId;
|
||||
const TArray<FString> OriginalCaseIds = Brief.FocusCaseIds;
|
||||
HyperTwistTrainingCoachLibraryInternal::ApplyPrimarySignalToBrief(Brief, Brief.Signals[0]);
|
||||
if (Brief.FocusDeckId.IsEmpty())
|
||||
{
|
||||
Brief.FocusDeckId = OriginalDeckId;
|
||||
}
|
||||
if (Brief.FocusMethodSegmentId.IsEmpty())
|
||||
{
|
||||
Brief.FocusMethodSegmentId = OriginalMethodSegmentId;
|
||||
}
|
||||
if (Brief.FocusCaseIds.Num() <= 0)
|
||||
{
|
||||
Brief.FocusCaseIds = OriginalCaseIds;
|
||||
}
|
||||
}
|
||||
|
||||
return Brief;
|
||||
}
|
||||
|
||||
FHyperTwistCoachScheduleHorizonSummary UHyperTwistTrainingCoachLibrary::DeriveCoachScheduleHorizonSummary(
|
||||
const FHyperTwistTrainingCoachSessionQueueState& QueueState,
|
||||
const FHyperTwistTrainingCoachArchivePolicySummary& ArchivePolicySummary,
|
||||
|
|
|
|||
|
|
@ -434,6 +434,13 @@ FHyperTwistTrainingCoachPanelState UHyperTwistTrainingSubsystem::GetActiveCoachP
|
|||
PanelState.PreferredQueueRecoveryAction = ActiveCoachMemorySnapshot.PreferredQueueRecoveryAction;
|
||||
PanelState.PreferredQueueRecoveryActionSourceLabel =
|
||||
ActiveCoachMemorySnapshot.PreferredQueueRecoveryActionSourceLabel;
|
||||
PanelState.PreferredLaunchBudgetBias = ActiveCoachMemorySnapshot.PreferredLaunchBudgetBias;
|
||||
PanelState.PreferredLaunchBudgetSourceLabel =
|
||||
ActiveCoachMemorySnapshot.PreferredLaunchBudgetSourceLabel;
|
||||
PanelState.BroadenedLaunchBudgetHistoryCount =
|
||||
ActiveCoachMemorySnapshot.BroadenedLaunchBudgetHistoryCount;
|
||||
PanelState.TightenedLaunchBudgetHistoryCount =
|
||||
ActiveCoachMemorySnapshot.TightenedLaunchBudgetHistoryCount;
|
||||
PanelState.bRepositoryVerificationPassed = ActiveRepositoryRoundTripVerification.bDidRoundTripPass;
|
||||
PanelState.bRepositoryVerificationNeedsAttention = ActiveRepositoryRoundTripVerification.ResolvedPath.IsEmpty()
|
||||
|| !ActiveRepositoryRoundTripVerification.bDidRoundTripPass;
|
||||
|
|
@ -2458,6 +2465,19 @@ void UHyperTwistTrainingSubsystem::RefreshRepositoryViews()
|
|||
);
|
||||
ActiveCoachSignals = ActiveCoachBrief.Signals;
|
||||
}
|
||||
const FHyperTwistCoachSignal LaunchBudgetHistorySignal =
|
||||
UHyperTwistTrainingCoachLibrary::DeriveLaunchBudgetHistorySignal(
|
||||
ActiveCoachMemorySnapshot,
|
||||
ActiveCoachBrief
|
||||
);
|
||||
if (!LaunchBudgetHistorySignal.SignalId.IsEmpty())
|
||||
{
|
||||
ActiveCoachBrief = UHyperTwistTrainingCoachLibrary::RefineCoachBriefWithLaunchBudgetHistorySignal(
|
||||
ActiveCoachBrief,
|
||||
LaunchBudgetHistorySignal
|
||||
);
|
||||
ActiveCoachSignals = ActiveCoachBrief.Signals;
|
||||
}
|
||||
ActiveCoachFollowUpBrief = ActiveCoachActionPlanOutcomeSummary.IsStructurallyValid()
|
||||
&& (
|
||||
ActiveCoachActionClosureSummary.bShouldSpawnFollowUp
|
||||
|
|
|
|||
|
|
@ -491,6 +491,18 @@ public:
|
|||
const FHyperTwistCoachSignal& ClosureRecoveryHistorySignal
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
static FHyperTwistCoachSignal DeriveLaunchBudgetHistorySignal(
|
||||
const FHyperTwistTrainingCoachMemorySnapshot& CoachMemorySnapshot,
|
||||
const FHyperTwistCoachBrief& CurrentBrief
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
static FHyperTwistCoachBrief RefineCoachBriefWithLaunchBudgetHistorySignal(
|
||||
const FHyperTwistCoachBrief& BaseBrief,
|
||||
const FHyperTwistCoachSignal& LaunchBudgetHistorySignal
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Coach")
|
||||
static FHyperTwistCoachScheduleHorizonSummary DeriveCoachScheduleHorizonSummary(
|
||||
const FHyperTwistTrainingCoachSessionQueueState& QueueState,
|
||||
|
|
|
|||
|
|
@ -4464,6 +4464,18 @@ struct FHyperTwistTrainingCoachPanelState
|
|||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PreferredQueueRecoveryActionSourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 PreferredLaunchBudgetBias = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PreferredLaunchBudgetSourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 BroadenedLaunchBudgetHistoryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 TightenedLaunchBudgetHistoryCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 SignalCount = 0;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue