XP Balance
SkillDev toolsPreserve Nypsi XP balance and present XP bonus breakdowns correctly. Use when modifying getXpBonus, calcEarnedGambleXp, calcEarnedHFMXp, fish/hunt/mine XP, XP upgrades or boosters, premium/level/gem XP effects, or the profile multiplier XP fields.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the XP Balance skill
What this skill tells your AI
The instructions your AI receives, as published by mxz7/nypsi in .agents/skills/xp-balance/SKILL.md and read by ahel’s review.
Treat XP changes as balance-sensitive. Separate source collection, command-specific calculation, and presentation.
Calculation boundaries
Work primarily in:
src/utils/functions/economy/xp.tssrc/commands/profile.tsfor presentation only- fish, hunt, and mine callers when verifying integration
Keep these responsibilities separate:
getXpBonus(member, client, guildId)collects account and guild-context bonus data.calcEarnedGambleXp()owns bet and gambling-multiplier adjustments.calcEarnedHFMXp()owns fish/hunt/mine item-count logic and HFM scaling.profile.tssorts and renders prepared breakdown data. Do not reproduce XP formulas there.
Never move bet, maximum-bet, or gambling multiplier behavior into getXpBonus().
Never change an earned-XP formula as an incidental refactor.
Bonus helper semantics
getXpBonus() currently builds:
min, starting at5max, calculated once asmin * 1.3boosterEffect, the additive multiplier effect used by earned-XP functionsbaseBreakdown, source values added tominmultiplierBreakdown, configured percentage-point sourcesrawLevel, used by command-specific logic
Base sources include capped raw level, Nitro/server boosting, premium tier, and gems. Preserve the actual randomly generated gem value. Do not replace it with an average, expected value, or newly generated display value.
Multiplier sources include the personal XP upgrade, active XP boosters, the active eagle pet roll,
and the official nypsi server bonus. The beginner booster is part of this path. Roll eagle in
getXpBonus, add its benefit to boosterEffect, and include its successful activation in
multiplierBreakdown.
When guildId === Constants.NYPSI_SERVER_ID, add the 7.5% official-server bonus to
boosterEffect as 0.075 and to multiplierBreakdown as 7.5, labelled official nypsi server.
Pass the originating guild ID through both XP calculation helpers and every caller. Crash is hosted
only in the official server, so its calls use Constants.NYPSI_SERVER_ID directly.
The official-server reward also includes a 1% gamble multiplier and 3% sell multiplier. Keep the
same guild context when calling getGambleMulti() and getSellMulti() so those helpers can add
their respective named breakdown entries. Background autosell has no command guild context and
therefore does not receive the server-specific sell bonus.
Do not reinterpret a baseBreakdown value:
10.8premium means premium added10.8to the minimum.- It does not mean
216% premium. - It is not a per-source minimum/maximum range.
- The global
max = min * 1.3does not turn every source into a range.
Gamble XP invariants
Keep required-bet checks, adjusted maximum bet, percentage-of-max-bet, command multiplier, random
roll, boosterEffect, clamping, and final flooring inside calcEarnedGambleXp().
Cap the gambling payout multiplier used for XP at 5x. Money payouts remain uncapped; this only prevents Dragon Tower and High-Low jackpots from producing extreme single-game XP awards.
The final Math.floor() means awarded XP is whole. Display XP breakdown values as whole XP without
changing the raw values used in calculation.
Fish/hunt/mine invariants
Fish and hunt use calcEarnedHFMXp() directly. Mine applies its existing division after that call.
Direct XP loot awarded outside this function is separate.
HFM obtains values from getXpBonus() and modifies them only in the HFM path:
min *= 1 + Math.log2(1 + xpBonus.min / 5) / 200;
max *= 1 + Math.log2(1 + xpBonus.max / 6.5) / 200;
Then apply xpBonus.boosterEffect and preserve the final floor. The /200 scaling is deliberate;
do not retune it casually.
All configured percentage sources apply to HFM. Base sources such as level, premium, Nitro, and
gems affect HFM through the logarithmic scaling. If a profile breakdown needs their HFM effect,
derive a prepared HFM breakdown in the XP domain code using the same scaling. Do not duplicate the
logarithmic calculation in profile.ts.
Exclude the no-bonus HFM baseline from a bonus breakdown. A default account's scaling is not a
0.5% base bonus source.
Profile display
Match the existing gamble and sell convention:
5% premium
Use compact value source rows:
35xp level
2xp gems
1.08% level
0.03% gems
Requirements:
- Use separate
xp (gamble)andxp (fish/hunt/mine)fields. - Place both XP fields side-by-side on the row below gamble and sell.
- Show every active source, including premium, level, Nitro, gems, upgrades, and boosters.
- Render gamble base entries as a single whole-XP value from the breakdown, not a range.
- Render HFM effects as percentages and percentage sources as their configured percentages.
- Omit zero-value sections and sources.
- Do not use formulas, explanatory prose, arrows, multiplier notation, or tildes.
- Do not invent a
totalthat mixes additive minimum XP with percentage multipliers. - If a spacer is required by Discord's three-column inline-field grid, use a zero-width field only for layout.
Balance validation
Before changing XP output:
- Record the current final formula and identify every changed term.
- Compare old and proposed outputs with identical item counts and controlled random inputs.
- Test fresh accounts, level 500, level 5000, and a full grinding loadout.
- Treat level 500 as beginner territory and level 5000 as representative of heavy players.
- Include maximum prestige/level, personal upgrades, all boosters, Nitro, platinum/premium, and guild boosters in the full-loadout case.
- Present comparable tables across cohorts and check that relative change is consistent.
Do not introduce arbitrary caps or discard helper data to force matching output. Do not describe a refactor as balance-preserving unless the end calculation is demonstrably unchanged.
Run make check after changes.
Level requirement formula
src/utils/functions/economy/levelling-formula.ts owns the XP required for a
level. Its calculateLevelXp() helper takes one raw level; keep direct level
requirements, next-prestige totals, and crate scaling routed through it.
The production curve implemented on 31 July 2026 has these locked cumulative checkpoints:
- P20:
2,154,413XP - P80:
48,762,535XP
The P80 checkpoint is 7.49% above the historical formula. Preserve the early
raw-level reset (100 is easier than 99) and the monotonic increase in both
complete-prestige costs and their first differences. At high prestige, the
growth between prestiges can exceed the small within-prestige reset, so do not
assume every first level after prestiging is cheaper than the preceding level.
Update test/utils/levelling-formula.test.ts whenever intentionally changing
the curve or its checkpoints.
Basic crate level rewards
cratesFormula() in src/utils/functions/economy/levelling-formula.ts owns the
variable basic-crate reward granted by level-ups. Reward frequency remains:
- every 30 raw levels before P15;
- every 25 raw levels from P15;
- every 20 raw levels from P30;
- every 15 raw levels from P40 onward.
The amount uses the average XP requirement of the current prestige and a
smoothly transitioning divisor. This keeps every qualifying reward within a
prestige consistent and prevents the reward amount from decreasing at divisor
boundaries. With the current XP curve, the cumulative target before P80 is
5,993 basic crates, 1.71% below the original 6,097.
Preserve monotonic qualifying rewards and check cumulative supply whenever
changing the XP curve, divisor transitions, or reward intervals. Separate fixed
milestone rewards such as Nypsi crates, 69420 crates, bronze credits, and omega
crates are not part of cratesFormula().
Signals
- GitHub stars
- 69
- Forks
- 31
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
xp-balance- Source
- github.com/mxz7/nypsi