feat(stats): make milestone computation pluggable via strategy#308
Merged
Conversation
Extract the milestone-VALUE choice in computeStatProgression into a pluggable MilestoneStrategy (value, trendingUpward, stat) => number, leaving the time-to-reach math untouched. The built-in nextNaturalMilestone reproduces today's behavior exactly: next prestige for stars, next whole number for fkdr/kdr, next round number otherwise. The strategy is an optional param on computeStatProgression (defaulting to nextNaturalMilestone) so callers can swap in different milestone schemes per place. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying rainbow with
|
| Latest commit: |
92b5181
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://602cc685.rainbow-ctx.pages.dev |
| Branch Preview URL: | https://feat-pluggable-milestone-str.rainbow-ctx.pages.dev |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR makes milestone target selection in computeStatProgression pluggable via a MilestoneStrategy callback, while keeping the existing time-to-reach solvers unchanged. It introduces a default nextNaturalMilestone strategy intended to preserve existing milestone behavior and adds unit tests covering both the default strategy and strategy injection.
Changes:
- Added
MilestoneStrategyand defaultnextNaturalMilestone, and threaded an optional strategy parameter throughcomputeStatProgression(and internal quotient/index paths). - Replaced hard-coded milestone selection logic for quotient, index, stars, and linear counters with calls to the strategy.
- Added new unit tests for
nextNaturalMilestoneand for strategy injection behavior incomputeStatProgression.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/stats/progression.ts | Introduces MilestoneStrategy/nextNaturalMilestone and applies the strategy throughout milestone selection in progression computations. |
| src/stats/progression.unit.test.ts | Adds unit tests for the default milestone strategy and for injected-strategy behavior in computeStatProgression. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
Summary
Extracts the milestone-value selection in
computeStatProgressioninto a pluggableMilestoneStrategy—(value, trendingUpward, stat) => number— while leaving the time-to-reach math (cubic solver forindex, linear algebra for ratios, etc.) untouched.The built-in
nextNaturalMilestonereproduces today's behavior exactly: next prestige forstars, next whole number forfkdr/kdr, next round number scaled to order of magnitude for everything else. It's wired as an optional trailing param oncomputeStatProgression(defaulting tonextNaturalMilestone), so callers can swap in a different scheme without touching the solvers.Contract: a strategy must return a value strictly greater than
valuewhen trending up, and strictly less when trending down — the solvers rely on this to keepdaysUntilMilestonenon-negative and correctly signed.Why
We want to be able to choose different milestone schemes in different places — in particular snappier, finer-grained milestones, which we'll use in #256. This PR is just the pluggable seam (the default preserves current behavior); the alternate "snappier" strategy and where it gets selected land in #256.
Tests
Built red-green; two new test families in
progression.unit.test.ts:nextNaturalMilestoneunit tests — stars/quotient/round-number, up & down, power-of-ten boundaries, non-positive clamp, and a strict-monotonic contract check.computeStatProgression— assert the injected strategy receives the expected(value, trendingUpward, stat)per stat type (including the dividend keyfinalKillsin the infinite-ratio path), and that its returned milestone is respected for simple linear / quotient / index / stars cases (withdaysUntilMilestonerecomputed accordingly).pnpm test:unit→ 562 passing (34 new; the prior suite is unchanged and green, confirming the default preserves behavior).pnpm tscand oxlint/oxfmt clean on the changed files.🤖 Generated with Claude Code