From 331366bd9b4455dbbb58d3c2479516a907fa807d Mon Sep 17 00:00:00 2001 From: Michael McCarty Date: Mon, 12 Oct 2026 17:27:46 -0700 Subject: [PATCH] :recycle: feat(leaderboard): rename prest/ EB keys, add aliases --- src/leaderboard/leaderboard.go | 16 ++-- src/leaderboard/leaderboard_calculators.go | 24 +++--- .../leaderboard_calculators_test.go | 82 +++++++++++-------- src/leaderboard/leaderboard_post.go | 2 +- src/leaderboard/leaderboard_post_test.go | 4 +- 5 files changed, 76 insertions(+), 52 deletions(-) diff --git a/src/leaderboard/leaderboard.go b/src/leaderboard/leaderboard.go index b730b276..5f1740ab 100644 --- a/src/leaderboard/leaderboard.go +++ b/src/leaderboard/leaderboard.go @@ -18,7 +18,9 @@ import ( // Leaderboard keys constants. const ( LBEarningsBonus = "eb" - LBPrestigedEarningsBonus = "prestiged_eb" + LBFutureEarningsBonus = "future_eb" + LBPendingEarningsBonus = LBFutureEarningsBonus // Deprecated: use LBFutureEarningsBonus + LBPrestigedEarningsBonus = LBEarningsBonus // Deprecated: use LBEarningsBonus LBSoulEggs = "soul_eggs" LBProphecyEggs = "prophecy_eggs" LBTerrorEvents = "terror_events" @@ -111,8 +113,8 @@ type LBGroup struct { var AllLeaderboards = []LBDef{ {Key: LBSoulEggs, DisplayName: "Soul Eggs", HeaderName: "SE", Description: "Total soul eggs collected.", ValueFmt: "ei", HigherIsBetter: true, Source: SourceFirstContact, RetainRecentOnly: true}, {Key: LBProphecyEggs, DisplayName: "Prophecy Eggs", HeaderName: "PE", Description: "Total eggs of prophecy collected.", ValueFmt: "int", HigherIsBetter: true, Source: SourceFirstContact, RetainRecentOnly: true}, - {Key: LBEarningsBonus, DisplayName: "Earnings Bonus", Description: "Nekkid and Dressed earnings bonus (includes pending TE).", ValueFmt: "eb", HigherIsBetter: true, Source: SourceFirstContact, RetainRecentOnly: true}, - {Key: LBPrestigedEarningsBonus, DisplayName: "Prestiged Earnings Bonus", Description: "Nekkid and Dressed earnings bonus (excludes pending TE).", ValueFmt: "eb", HigherIsBetter: true, Source: SourceFirstContact, RetainRecentOnly: true}, + {Key: LBEarningsBonus, DisplayName: "Earnings Bonus", Description: "Nekkid and Dressed earnings bonus (excludes pending TE).", ValueFmt: "eb", HigherIsBetter: true, Source: SourceFirstContact, RetainRecentOnly: true}, + {Key: LBFutureEarningsBonus, DisplayName: "Future Earnings Bonus", Description: "Nekkid and Dressed earnings bonus (includes pending TE).", ValueFmt: "eb", HigherIsBetter: true, Source: SourceFirstContact, RetainRecentOnly: true}, {Key: LBVirtueShifts, DisplayName: "Virtue Shifts", HeaderName: "Shifts", Description: "Total virtue shifts completed.", ValueFmt: "int", HigherIsBetter: true, Source: SourceFirstContact, RetainRecentOnly: true}, {Key: LBTETotal, DisplayName: "Total Truth Eggs", HeaderName: "TE", Description: "Sum of truth eggs across all virtues.", ValueFmt: "int", HigherIsBetter: true, Source: SourceFirstContact, RetainRecentOnly: true}, {Key: LBCTETotal, DisplayName: "Total CTE", HeaderName: "CTE", Description: "Clothed Truth Egg equivalent for pending and current TE.", ValueFmt: "int", HigherIsBetter: true, Source: SourceFirstContact, RetainRecentOnly: true}, @@ -142,7 +144,7 @@ var AllGroups = []LBGroup{ { Key: "group_core", DisplayName: "EB Stats", - Members: []string{LBEarningsBonus, LBPrestigedEarningsBonus, LBSoulEggs, LBProphecyEggs, LBTETotal, LBCTETotal, LBVirtueShifts, LBPrestiges}, + Members: []string{LBEarningsBonus, LBFutureEarningsBonus, LBSoulEggs, LBProphecyEggs, LBTETotal, LBCTETotal, LBVirtueShifts, LBPrestiges}, }, { Key: "group_cs_stats", @@ -287,7 +289,11 @@ var legacyKeyAliases = map[string]string{ "cxp_weekly_delta": LBCXPWeeklyDelta, "group_prestige_stats": "group_misc", LBVirtueTEEarnedSum: LBVirtueEggsSum, - "eb_prestiged": LBPrestigedEarningsBonus, + "prestiged_eb": LBEarningsBonus, + "eb_prestiged": LBEarningsBonus, + "pending_eb": LBFutureEarningsBonus, + "eb_pending": LBFutureEarningsBonus, + "eb_future": LBFutureEarningsBonus, } func resolveAlias(key string) string { diff --git a/src/leaderboard/leaderboard_calculators.go b/src/leaderboard/leaderboard_calculators.go index 68ea2bc5..c5c7fdc8 100644 --- a/src/leaderboard/leaderboard_calculators.go +++ b/src/leaderboard/leaderboard_calculators.go @@ -203,7 +203,7 @@ func RunCalculators( emit(LBEntry{LBType: LBSoulEggs, Player: userID, GameName: gameName, SnapDate: snapDate, Value: game.GetSoulEggsD()}) emit(LBEntry{LBType: LBProphecyEggs, Player: userID, GameName: gameName, SnapDate: snapDate, Value: float64(game.GetEggsOfProphecy())}) - // For Earnings Bonus, we need total Truth Eggs (EoV) including pending TE + // For Future Earnings Bonus, we need total Truth Eggs (EoV) including pending TE totalTE := 0.0 if virtue != nil { deliveries := virtue.GetEggsDelivered() @@ -211,28 +211,28 @@ func RunCalculators( totalTE += float64(ei.CountTruthEggTiersPassed(deliveries[i])) } } - nakedEB := ei.GetEarningsBonus(backup, totalTE) - dressedEB := ei.GetDressedEarningsBonus(backup, totalTE) + futureNakedEB := ei.GetEarningsBonus(backup, totalTE) + futureDressedEB := ei.GetDressedEarningsBonus(backup, totalTE) emit(LBEntry{ - LBType: LBEarningsBonus, + LBType: LBFutureEarningsBonus, Player: userID, GameName: gameName, SnapDate: snapDate, - Value: nakedEB, - Details: fmt.Sprintf("dressed:%.6f", dressedEB), + Value: futureNakedEB, + Details: fmt.Sprintf("dressed:%.6f", futureDressedEB), }) - // For Prestiged Earnings Bonus, we use credited/prestiged Truth Eggs (excludes pending TE) + // For Earnings Bonus, we use credited/prestiged Truth Eggs (excludes pending TE) prestigedTE := float64(ei.GetCurrentTruthEggs(backup)) - prestigedNakedEB := ei.GetEarningsBonus(backup, prestigedTE) - prestigedDressedEB := ei.GetDressedEarningsBonus(backup, prestigedTE) + nakedEB := ei.GetEarningsBonus(backup, prestigedTE) + dressedEB := ei.GetDressedEarningsBonus(backup, prestigedTE) emit(LBEntry{ - LBType: LBPrestigedEarningsBonus, + LBType: LBEarningsBonus, Player: userID, GameName: gameName, SnapDate: snapDate, - Value: prestigedNakedEB, - Details: fmt.Sprintf("dressed:%.6f", prestigedDressedEB), + Value: nakedEB, + Details: fmt.Sprintf("dressed:%.6f", dressedEB), }) } diff --git a/src/leaderboard/leaderboard_calculators_test.go b/src/leaderboard/leaderboard_calculators_test.go index 43292605..7188e382 100644 --- a/src/leaderboard/leaderboard_calculators_test.go +++ b/src/leaderboard/leaderboard_calculators_test.go @@ -21,31 +21,31 @@ func TestRunCalculators_EarningsBonusPendingVsPrestiged(t *testing.T) { "user-test-1", backup, nil, - []string{LBEarningsBonus, LBPrestigedEarningsBonus}, + []string{LBEarningsBonus, LBFutureEarningsBonus}, "2026-10-12", 0, ) - var entryEB, entryPrestigedEB *LBEntry + var entryEB, entryFutureEB *LBEntry for i := range entries { if entries[i].LBType == LBEarningsBonus { entryEB = &entries[i] } - if entries[i].LBType == LBPrestigedEarningsBonus { - entryPrestigedEB = &entries[i] + if entries[i].LBType == LBFutureEarningsBonus { + entryFutureEB = &entries[i] } } if entryEB == nil { t.Fatalf("expected %s entry to be emitted", LBEarningsBonus) } - if entryPrestigedEB == nil { - t.Fatalf("expected %s entry to be emitted", LBPrestigedEarningsBonus) + if entryFutureEB == nil { + t.Fatalf("expected %s entry to be emitted", LBFutureEarningsBonus) } - if entryEB.Value <= entryPrestigedEB.Value { - t.Errorf("expected Earnings Bonus (%f) to be strictly greater than Prestiged Earnings Bonus (%f) when pending TE > 0", - entryEB.Value, entryPrestigedEB.Value) + if entryFutureEB.Value <= entryEB.Value { + t.Errorf("expected Future Earnings Bonus (%f) to be strictly greater than Earnings Bonus (%f) when pending TE > 0", + entryFutureEB.Value, entryEB.Value) } // 2. Without pending TE (earned TE matches tiers passed) @@ -59,28 +59,28 @@ func TestRunCalculators_EarningsBonusPendingVsPrestiged(t *testing.T) { "user-test-1", backup, nil, - []string{LBEarningsBonus, LBPrestigedEarningsBonus}, + []string{LBEarningsBonus, LBFutureEarningsBonus}, "2026-10-12", 0, ) - var entryEB2, entryPrestigedEB2 *LBEntry + var entryEB2, entryFutureEB2 *LBEntry for i := range entriesNoPending { if entriesNoPending[i].LBType == LBEarningsBonus { entryEB2 = &entriesNoPending[i] } - if entriesNoPending[i].LBType == LBPrestigedEarningsBonus { - entryPrestigedEB2 = &entriesNoPending[i] + if entriesNoPending[i].LBType == LBFutureEarningsBonus { + entryFutureEB2 = &entriesNoPending[i] } } - if entryEB2 == nil || entryPrestigedEB2 == nil { + if entryEB2 == nil || entryFutureEB2 == nil { t.Fatalf("expected both entries to be emitted when no pending TE") } - if entryEB2.Value != entryPrestigedEB2.Value { - t.Errorf("expected Earnings Bonus (%f) to equal Prestiged Earnings Bonus (%f) when pending TE == 0", - entryEB2.Value, entryPrestigedEB2.Value) + if entryEB2.Value != entryFutureEB2.Value { + t.Errorf("expected Earnings Bonus (%f) to equal Future Earnings Bonus (%f) when pending TE == 0", + entryEB2.Value, entryFutureEB2.Value) } } @@ -89,38 +89,56 @@ func TestEarningsBonusRegistryDefinitions(t *testing.T) { if !okEB { t.Fatalf("expected definition for %s", LBEarningsBonus) } - if !strings.Contains(defEB.Description, "pending TE") { - t.Errorf("expected %s description to mention pending TE, got %q", LBEarningsBonus, defEB.Description) + if defEB.DisplayName != "Earnings Bonus" { + t.Errorf("expected %s display name to be 'Earnings Bonus', got %q", LBEarningsBonus, defEB.DisplayName) + } + if !strings.Contains(defEB.Description, "excludes pending TE") { + t.Errorf("expected %s description to mention excluding pending TE, got %q", LBEarningsBonus, defEB.Description) } - defPrestigedEB, okPrestigedEB := LBDefByKey(LBPrestigedEarningsBonus) - if !okPrestigedEB { - t.Fatalf("expected definition for %s", LBPrestigedEarningsBonus) + defFutureEB, okFutureEB := LBDefByKey(LBFutureEarningsBonus) + if !okFutureEB { + t.Fatalf("expected definition for %s", LBFutureEarningsBonus) + } + if defFutureEB.DisplayName != "Future Earnings Bonus" { + t.Errorf("expected %s display name to be 'Future Earnings Bonus', got %q", LBFutureEarningsBonus, defFutureEB.DisplayName) } - if !strings.Contains(defPrestigedEB.Description, "excludes pending TE") { - t.Errorf("expected %s description to mention excluding pending TE, got %q", LBPrestigedEarningsBonus, defPrestigedEB.Description) + if !strings.Contains(defFutureEB.Description, "includes pending TE") { + t.Errorf("expected %s description to mention including pending TE, got %q", LBFutureEarningsBonus, defFutureEB.Description) } - // Verify alias - if resolveAlias("eb_prestiged") != LBPrestigedEarningsBonus { - t.Errorf("expected alias eb_prestiged to resolve to %s, got %s", LBPrestigedEarningsBonus, resolveAlias("eb_prestiged")) + // Verify aliases + if resolveAlias("prestiged_eb") != LBEarningsBonus { + t.Errorf("expected alias prestiged_eb to resolve to %s, got %s", LBEarningsBonus, resolveAlias("prestiged_eb")) + } + if resolveAlias("eb_prestiged") != LBEarningsBonus { + t.Errorf("expected alias eb_prestiged to resolve to %s, got %s", LBEarningsBonus, resolveAlias("eb_prestiged")) + } + if resolveAlias("pending_eb") != LBFutureEarningsBonus { + t.Errorf("expected alias pending_eb to resolve to %s, got %s", LBFutureEarningsBonus, resolveAlias("pending_eb")) + } + if resolveAlias("eb_pending") != LBFutureEarningsBonus { + t.Errorf("expected alias eb_pending to resolve to %s, got %s", LBFutureEarningsBonus, resolveAlias("eb_pending")) + } + if resolveAlias("eb_future") != LBFutureEarningsBonus { + t.Errorf("expected alias eb_future to resolve to %s, got %s", LBFutureEarningsBonus, resolveAlias("eb_future")) } // Verify group_core contains both groupCoreMembers := ExpandConfigKey("group_core") - foundEB, foundPrestigedEB := false, false + foundEB, foundFutureEB := false, false for _, m := range groupCoreMembers { if m == LBEarningsBonus { foundEB = true } - if m == LBPrestigedEarningsBonus { - foundPrestigedEB = true + if m == LBFutureEarningsBonus { + foundFutureEB = true } } if !foundEB { t.Errorf("expected %s in group_core members", LBEarningsBonus) } - if !foundPrestigedEB { - t.Errorf("expected %s in group_core members", LBPrestigedEarningsBonus) + if !foundFutureEB { + t.Errorf("expected %s in group_core members", LBFutureEarningsBonus) } } diff --git a/src/leaderboard/leaderboard_post.go b/src/leaderboard/leaderboard_post.go index a9a09177..a35494d8 100644 --- a/src/leaderboard/leaderboard_post.go +++ b/src/leaderboard/leaderboard_post.go @@ -696,7 +696,7 @@ func renderTable(def LBDef, rows []LBEntry, prevMap map[string]float64, rankOffs rankWidth := runewidth.StringWidth(rankHeader) maxValOnlyWidth := runewidth.StringWidth(shortDisplayName) - isEB := def.Key == LBEarningsBonus || def.Key == LBPrestigedEarningsBonus + isEB := def.Key == LBEarningsBonus || def.Key == LBFutureEarningsBonus hasCTEComparisonColumn := def.Key == LBCTETotal hasTEColumn := def.Key == LBEggsCuriosity || def.Key == LBEggsIntegrity || def.Key == LBEggsHumility || def.Key == LBEggsResilience || def.Key == LBEggsKindness || def.Key == LBVirtueEggsSum teWidth := runewidth.StringWidth("TE") diff --git a/src/leaderboard/leaderboard_post_test.go b/src/leaderboard/leaderboard_post_test.go index 01ed89ec..b1aaaabd 100644 --- a/src/leaderboard/leaderboard_post_test.go +++ b/src/leaderboard/leaderboard_post_test.go @@ -50,7 +50,7 @@ func TestRenderTable_AllLeaderboards(t *testing.T) { } switch { - case def.Key == LBEarningsBonus || def.Key == LBPrestigedEarningsBonus: + case def.Key == LBEarningsBonus || def.Key == LBFutureEarningsBonus: row.Details = "dressed:23456" case def.Key == LBCXPWeeklyDelta: row.Details = "na" @@ -127,7 +127,7 @@ func TestRenderTable_AllLeaderboards(t *testing.T) { } } - if def.Key == LBEarningsBonus || def.Key == LBPrestigedEarningsBonus { + if def.Key == LBEarningsBonus || def.Key == LBFutureEarningsBonus { if !strings.Contains(colHeader, "Nekkid") || !strings.Contains(colHeader, "Dressed") { t.Fatalf("expected EB columns for %s, got %q", def.Key, colHeader) }