core/player_progression_service
library
Classes
-
LevelDefinition
-
One rung of the XP curve. level is 1-based; the LAST entry in a curve
must have xpToNext
== 0 — that's what marks it the max level (nothing
further to grind toward). Every other entry needs xpToNext > 0, and the
curve must be non-decreasing (a later level never costs less XP to clear
than an earlier one) — see validateLevelCurve.
-
LevelUpEvent
-
Fired once per level actually crossed by a PlayerProgressionService.grantXp
call — a single call that jumps several levels at once fires one of these
per level, in ascending order.
-
PlayerProgressionService
-
Single source of truth for one player's XP/level — persists
PlayerProgressionSnapshot.totalXpEarned (never level/xpIntoLevel
directly, both are always re-derived from it and the curve) plus a
bounded idempotency ledger, same pattern as
EconomyWallet/
RewardTransactionPipeline (FEAT-31/FEAT-42): a corrupt save resets to
a fresh, never-exploitable state instead of throwing or trusting a
partially-decoded value.
-
PlayerProgressionSnapshot
-
Reactive snapshot of one player's progression — level/xpIntoLevel/
xpToNextLevel are always derived fresh from totalXpEarned against the
curve (never persisted directly), so they can never drift out of sync
with it.