One clock, one DAILY panel, and a prune that knows what /stats reads - #215
Merged
Conversation
Closes the two items §9b left open, and the thing the owner spotted while watching the map. 1. THE DAILY MENU OPENED SOMEWHERE ELSE Owner: "itu sebuah menu yang kalo di klik yang muncul malah di luar, bukan di dalam menu daily itu sendiri." Exactly right, and it was worse than misplaced. Every other rail button — Rewards, Pass, Bag, Shop, Craft, Settings — opens a screen. DAILY dispatched an event that expanded a strip at the BOTTOM of the map, nowhere near the icon pressed. And the strip held only the contracts, while the streak, fragments, energy and craft — all equally daily — sat as chips somewhere else. "Daily" was three places, and one of them behaved unlike its neighbours. It is one panel now, holding all five, opened by the rail button OR by any chip. The chips stay on the bar because they are the glance and what is at risk has to be visible without a tap; the panel is the detail, and there is one of it. Closes on ✕ or on tapping outside — a panel over a map that can only be dismissed one way is a trap. 2. TWO CLOCKS ON ONE BAR Energy refilled on a rolling 24h from first use while contracts and the streak reset at 00:00 UTC. A player who played at 20:00 got new contracts four hours later and new energy twenty-four hours later, with nothing on screen explaining the difference. Energy is on the UTC day now. windowStart keeps its name and type and holds the day it was spent against, so records written by the old code compare as an earlier day and reset on first read: no migration, and nobody gains or loses a run at the changeover. windowHours is deleted — nothing read it once the boundary moved, and a config value nothing reads is exactly how game-config.ts became a liability. Slightly more generous (play at 20:00, allowance back at midnight). A deliberate trade: the $1 refill sells to players who want more than five in one sitting, and that motivation is untouched. What it buys is one clock — and it is what lets the panel show a single honest countdown. A "resets in 1h 27m" over three chips on two different clocks would have been a lie about one of them. 3. NOTHING PRUNED THE DAILY/WEEKLY BUCKETS prune() now runs on the same daily cron: dailyContracts, dailyContractClaims and passPerkClaims older than 30 days, vaultFragments older than 8 weeks. It does NOT touch paperClaims, goldenKeyClaims or vaultCompleted, because /api/stats counts LIFETIME totals out of those three — pruning them would shrink the public stats page, and the drop would read as players leaving rather than as rows being deleted. There is a test naming each of the three. A key whose shape is not recognised is never stale, so a malformed bucket is left alone rather than guessed at. The prune is caught, not thrown: a housekeeping failure must never stop a season being frozen. test:season 45 -> 66. test:contracts rewritten for the panel, including that DAILY opens something holding more than contracts. 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.
Closes the two items the audit (§9b) deliberately left open, plus the thing the owner spotted while watching the map.
No smart contract, ABI, or contract address is touched.
1. The DAILY menu opened somewhere else
Exactly right, and it was worse than misplaced:
"Daily" was three places, and one of them behaved unlike its neighbours.
It is one panel now, holding all five, opened by the rail button or by any chip. The chips stay on the bar because they are the glance and what is at risk has to be visible without a tap; the panel is the detail, and there is one of it. Closes on ✕ or on tapping outside — a panel over a map that can only be dismissed one way is a trap.
2. Two clocks on one bar
Energy refilled on a rolling 24h from first use while contracts and the streak reset at 00:00 UTC. A player who played at 20:00 got new contracts four hours later and new energy twenty-four hours later, with nothing on screen explaining the difference.
Energy is on the UTC day now.
windowStartkeeps its name and type and holds the day it was spent against, so records written by the old code compare as an earlier day and reset on first read — no migration, and nobody gains or loses a run at the changeover.windowHoursis deleted: nothing read it once the boundary moved, and a config value nothing reads is exactly howgame-config.tsbecame a liability.This is slightly more generous (play at 20:00, allowance back at midnight). A deliberate trade — the $1 refill sells to players who want more than five in one sitting, and that motivation is untouched.
What it buys is one clock, and it is what lets the panel show a single honest countdown. "Resets in 1h 27m" over three chips on two different clocks would have been a lie about one of them.
3. Nothing pruned the daily/weekly buckets
prune()now runs on the same daily cron:dailyContracts,dailyContractClaims,passPerkClaimsolder than 30 days, andvaultFragmentsolder than 8 weeks.It does not touch
paperClaims,goldenKeyClaimsorvaultCompleted—/api/statscounts lifetime totals out of those three. Pruning them would shrink the public stats page, and the drop would read as players leaving rather than as rows being deleted. There is a test naming each of the three specifically.A key whose shape is not recognised is never stale, so a malformed bucket is left alone rather than guessed at. The prune is caught, not thrown: housekeeping failing must never stop a season being frozen.
Verification
npm run test:seasonnpm run test:contractstest:play·test:raid·test:floors·test:audio·test:streak-ui·test:bunkers-ui·test:season-routestest:streak·test:seeded·test:bunkers·test:inventory·test:migratetest:traversableaudit·check:copy·check:market·check:cssvars·check:attributiontsc --noEmitlintbuildDocs: §5.5 gains the panel and the reason it is a panel, §9b records both closed items, and
game-mechanics.mdnow tells players everything daily resets together at 00:00 UTC.Generated by Claude Code