Releases: echecsjs/elo
Releases · echecsjs/elo
Release list
v4.0.2
v4.0.1
Fixed
- documented
delta,expected, andkFactorfunctions - documented all exported types (
GameOptions,GameType,KFactorOptions,
PlayerOptions,Result,ResultAndOpponent) - documented
PlayerOptions.koverride field - removed broken
CONTRIBUTING.mdlink
v4.0.0
Changed
- BREAKING:
expected()now uses the official FIDE §8.1.2 discrete lookup
table instead of the continuous formula. Return values are now discrete (0.50,
0.51, ..., 1.00) matching FIDE exactly. For rating differences > 735 (only
possible via the 2650+ cap exemption), the continuous formula is used as a
fallback.
Added
- Source comment in
kFactor()citing FIDE Rapid & Blitz regulations for K=20. - Integration test confirming the 2650+ cap exemption propagates correctly
throughupdate().
v3.1.0
Fixed
expected(): players rated 2650 or above are no longer subject to the
400-point rating difference cap, per FIDE §8.3.1 (effective 1 October 2025).update(): rating changes of exactly ±0.5 now round away from zero (e.g. −0.5
→ −1), as required by FIDE §8.3.4.
v3.0.0
Added
gamesInPeriodoption inKFactorOptionsandPlayerOptions— when
provided, applies the FIDE §8.3.3 K-factor cap: ifK × n > 700, K is reduced
toMath.floor(700 / n). ThrowsRangeErrorifgamesInPeriodis not a
positive integer.
Changed
kFactor()return type widened from10 | 20 | 40tonumberto accommodate
capped values.
v2.3.0
Added
initial(games: ResultAndOpponent[])function implementing FIDE §8.2 initial
rating calculation for unrated players. Injects two hypothetical 1800-rated
draws per the spec, caps result at 2200, and reuses the existing
ResultAndOpponenttype.
v2.2.1
Changed
- Updated README with friendlier intro, quick start section, annotated usage
examples, and FIDE compliance selling points
v2.2.0
Changed
KFactorOptionsandPlayerOptions:gamesfield renamed togamesPlayed
for clarity
Migration
// Before
kFactor({ games: 5, rating: 1400 });
update({ games: 30, rating: 1400 }, 1600, 1);
// After
kFactor({ gamesPlayed: 5, rating: 1400 });
update({ gamesPlayed: 30, rating: 1400 }, 1600, 1);v2.1.0
Added
GameTypetype ('blitz' | 'rapid' | 'standard') exported from the package
Changed
KFactorOptionsandGameOptionsnow usegameType?: GameTypeinstead of
the mutually exclusiveisBlitz?: boolean/isRapid?: booleanpair
Removed
isBlitzandisRapidfields removed fromKFactorOptionsand
GameOptions; usegameType: 'blitz'orgameType: 'rapid'instead
Migration
Replace isBlitz: true with gameType: 'blitz' and isRapid: true with
gameType: 'rapid' everywhere. The field appears in both kFactor options and
the GameOptions third argument of update.
// Before
kFactor({ isBlitz: true, rating: 1400 });
kFactor({ isRapid: true, rating: 2400 });
update(1400, 1600, { isBlitz: true, result: 1 });
update(1400, 1600, { isRapid: true, result: 1 });
// After
kFactor({ gameType: 'blitz', rating: 1400 });
kFactor({ gameType: 'rapid', rating: 2400 });
update(1400, 1600, { gameType: 'blitz', result: 1 });
update(1400, 1600, { gameType: 'rapid', result: 1 });Player options are unaffected — they still go on the player arguments:
update({ age: 17, rating: 1400 }, 1600, { gameType: 'blitz', result: 1 });v2.0.0
Changed
update()now acceptsPlayerOptionsobjects foraandbparameters,
allowing per-player options (age,games,everHigher2400,k) to be
passed directly on each player argument- Game-level options (
isBlitz,isRapid,result) are now passed as a
GameOptionsobject in the third argument
Removed
UpdateOptionstype removed from public API; usePlayerOptionsand
GameOptionsinsteadkA,kB,k(shared) fields removed from third argument; usekon each
PlayerOptionsobject instead
Migration
The third argument is now a GameOptions object (or a bare Result shorthand
when no game options are needed). Player-specific options move onto each player
argument as a PlayerOptions object.
// Before — flat options bag
update(1400, 1600, { result: 1 });
update(1400, 1600, { ageA: 17, result: 1 });
update(1400, 1600, { gamesB: 5, result: 1 });
update(1400, 1600, { kA: 40, result: 1 });
update(1400, 1600, { kA: 40, kB: 10, result: 1 });
update(1400, 1600, { isBlitz: true, result: 1 });
// After — per-player objects + game options
update(1400, 1600, 1); // bare result shorthand still works
update({ age: 17, rating: 1400 }, 1600, 1); // age on player A
update(1400, { games: 5, rating: 1600 }, 1); // games on player B
update({ k: 40, rating: 1400 }, 1600, 1); // k on player A
update({ k: 40, rating: 1400 }, { k: 10, rating: 1600 }, 1); // k on each player
update(1400, 1600, { gameType: 'blitz', result: 1 }); // game-level option