miaoda-game-progression-core
v0.3.2
Published
Engine-agnostic XP / level-curve engine — turn a running experience total into a level, tell you how much XP the current level still needs, and hand back the exact deltas when awarding XP crosses one or more level boundaries at once. Curves are a formula,
Maintainers
Readme
miaoda-game-progression-core
Use this engine-independent package when a game turns cumulative XP into levels, level-up rewards, or level-gated unlocks. It works with Cocos, Phaser, React, or a server process because it has no rendering or engine dependency.
Install
pnpm add miaoda-game-progression-coreMinimal example
import { LevelCurve, Progression } from 'miaoda-game-progression-core';
const curve = new LevelCurve({ step: (level) => 100 * level, maxLevel: 20 });
const hero = new Progression(curve);
const gain = hero.addXp(250);
console.log(hero.level, hero.xpIntoLevel, hero.xpToNext); // 2, 150, 50
console.log(gain.levelsReached); // [2]addXp returns every level entered, in order. A large award can therefore drive rewards for several levels:
hero.onLevelUp((level) => grantLevelReward(level));
const gain = hero.addXp(10_000);
for (const level of gain.levelsReached) showLevelUp(level);At maxLevel, surplus XP is ignored. progress is a fraction from 0 to 1, and xpToNext is 0 at the cap.
Choose a curve
Provide exactly one curve form:
| Configuration | Use it for |
| --- | --- |
| step: (fromLevel) => cost | Formula-based curves such as 100 * level |
| costs: number[] | A hand-tuned per-level cost table |
| totals: number[] | Cumulative thresholds that already start with 0 |
startLevel defaults to 1. A finite curve needs non-negative finite costs; an uncapped formula must return positive costs so level lookup can progress.
The step callback must return a finite, positive XP cost for every queried level.
Unlocks and saving
import { UnlockTable } from 'miaoda-game-progression-core';
const unlocks = new UnlockTable([
{ level: 1, value: 'attack' },
{ level: 5, value: 'shop' },
]);
unlocks.unlockedAt(hero.level);
unlocks.newlyUnlocked(2, hero.level);Save only totalXp; the curve derives the level and progress again. Restoring with new Progression(curve, { totalXp }) or setTotalXp(totalXp) does not replay level-up listeners. Keep reward grants separate from restoration.
Public API
LevelCurve: cumulative XP/level math and next-level thresholds.Progression: one entity's XP, level, progress, awards, and level-up listeners.UnlockTable: values unlocked at or between level ranges.XpGain,LevelUpListener,Gate: types for award results and unlock definitions.
Pair the level-up listener with miaoda-game-stats-core when level rewards should change stat bases; this package does not own inventory, stats, or UI.
