The season score punished the players who had been here longest - #233
Merged
Conversation
OWNER, Season 2, from the live board: *"pake wallet lainnya kills terhitung tp
xp tidak."* His row read 30 kills and 0 XP.
Season XP was a difference against a BASELINE — career XP now, minus career XP
when the season started. Career XP is stored as a high-water mark, because a
New Game legitimately restarts at 0 and must not erase it. Put the two together
and a returning player is frozen:
stored career xp (Season 1) .... 8581
baseline for Season 2 .......... 8581
this run's xp .................. 585
max(8581, 585) - 8581 .......... 0
They earn nothing for the season until ONE RUN beats their all-time best. A
brand-new wallet is baselined at 0 and works perfectly — which is why some
accounts looked right, others sat at zero, and the whole thing survived a month.
It is also why kills looked fine on the same row: recordRunKills has always
accumulated a delta.
THE FIX IS THE SHAPE THAT ALREADY WORKED. seasonXpGain remembers what was last
reported and adds the increase:
never reported before -> 0 anchor, do not pay
higher than last time -> the increase
LOWER than last time -> the whole figure (a run restarted)
That third line is what the baseline could never express. A restart used to
read as "no progress, forever"; it now counts in full.
MIGRATION NEEDS NO BACKFILL. Every existing doc has no lastRecordedXp, so it
lands on the anchor case exactly once and starts earning from the next report.
Season totals already banked are added to, not replaced — nobody loses what
they have, and nobody is handed their career total as a season score.
seasonBaseXp and seasonId are no longer written to the leaderboard doc, and
seasonBaseline is deleted rather than left exported. A baseline nothing
computes against is a value whose only remaining power is to mislead whoever
reads it next.
Both writers — updateLeaderboardEntry and recordRunProgress — now accumulate
through the same helper and the same lastRecordedXp, so re-reporting an
unchanged figure is worth zero and they cannot double-count each other.
updateLeaderboardEntry gained a second read; both transactions were re-checked
against the read-before-write rule that already cost this file every kill for a
month, and the test asserts it for every transaction in the module.
Verified: 19/19 test:seasonxp (rewritten, and it fails on the old baseline),
8/8 test:kills, 128/128 test-season-close, tsc clean, build unchanged at
143/242 kB, lint 35.
Season 2 is running, so the board changes on deploy: veterans stop reading 0
and start banking what they earn from their next sync.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017A764RdnwpyWnG7uCNhMiQ
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The owner's Season 2 row read 30 kills and 0 XP.
Season XP was a difference against a baseline — career XP now, minus career XP when the season started. Career XP is stored as a high-water mark, because a New Game legitimately restarts at 0 and must not erase it. Put the two together and a returning player is frozen:
They earn nothing for the season until one run beats their all-time best. A brand-new wallet is baselined at 0 and works perfectly — which is why some accounts looked right, others sat at zero, and the whole thing survived a month.
It is also why kills looked fine on the same row:
recordRunKillshas always accumulated a delta.The fix is the shape that already worked
seasonXpGainremembers what was last reported and adds the increase:That third row is what the baseline could never express. A restart used to read as "no progress, forever"; it now counts in full.
Migration needs no backfill
Every existing doc has no
lastRecordedXp, so it lands on the anchor case exactly once and starts earning from the next report. Season totals already banked are added to, not replaced — nobody loses what they have, and nobody is handed their career total as a season score.seasonBaseXpandseasonIdare no longer written, andseasonBaselineis deleted rather than left exported. A baseline nothing computes against is a value whose only remaining power is to mislead whoever reads it next.Both writers, one rule
updateLeaderboardEntryandrecordRunProgressnow accumulate through the same helper and the samelastRecordedXp, so re-reporting an unchanged figure is worth zero and they cannot double-count each other.updateLeaderboardEntrygained a second read. Both transactions were re-checked against the read-before-write rule that already cost this file every kill for a month — and the test now asserts it for every transaction in the module, not just the one that broke.Testing
Including a full simulated month — anchor, two runs, a New Game, two more — asserting the season sums to what was actually earned while the career high-water mark stays untouched.
On deploy
Season 2 is running, so the board changes: veterans stop reading 0 and start banking what they earn from their next sync onward. XP earned before the fix, while the baseline was swallowing it, cannot be recovered — it was never written anywhere.
Generated by Claude Code