hax-standard-elo
v0.3.2
Published
Standard Elo Plugin for Haxball Rooms
Downloads
173
Readme
Haxball Standard Elo
Plugin for calculating ranking points according to Elo system. To be used with node package haxball.js
Installation
npm i hax-standard-elo
Documentation
Website documentation is available at jakjus.github.io/hax-standard-elo/
Usage
Your haxball room can use in-memory database, SQL database or other. You must provide functions that get and set elo in your own room's data access layer. All the other calculations will be handled by plugin.
GetElo
- getting data of a player (including Elo)ChangeElo
- changing data of a player
You can find these definitions at docs.
Getting Started
The following example uses in-process memory within Haxball.js room script.
// room.js
const HaxballJS = require("haxball.js");
const { calculateChanges, execChanges } = require("hax-standard-elo");
const getRoom = async () => {
const HBInit = await HaxballJS
const room = HBInit({
roomName: 'test',
token: 'yourtokenhere'
})
return room
}
// example of in-memory data storage
const memory = {}
const run = async () => {
const room = await getRoom()
room.onPlayerJoin = (player) => {
room.setPlayerAdmin(player.id, true)
if (!memory[player.id]) {
memory[player.id] = {...player, elo: 1200}
}
}
// implement get and change functions for our memory type
const getEloOfPlayer = async (playerId) => memory[playerId].elo
const changeEloOfPlayer = (playerId, change) => {
memory[playerId].elo += change
}
room.onTeamVictory = async _ => {
try {
const changeList = await calculateChanges(room, getEloOfPlayer)
console.log(changeList)
await execChanges(changeList, getEloOfPlayer, changeEloOfPlayer)
console.log(memory)
} catch(e) {
console.log(e)
}
}
room.onRoomLink = link => {
console.log(link)
}
}
run()
The equivalent example for TypeScript is in room.ts.
Example for SQL DB
For SQL database, getEloOfPlayer
could be:
// ...init sqlite package and db
const getEloOfPlayer = async (playerId) =>
{
db.all(`SELECT elo FROM player WHERE playerId = ?`, [playerId], (err, rows) => {
rows.forEach((row) => return row.elo)
})
}
// do the adequate SQL query for changeEloOfPlayer
// const changeEloOfPlayer = ...
Logic
This library uses Elo rating system as shown in the Wikipedia. Elo was designed for 1v1 (2 entities competing against each other) with no draws. Therefore, to make it feasible in many players vs many players scenario, each player is changed using his individual elo and enemy team average elo. It helps having normally distributed Elo rankings across playerbase with smaller variance.
Build
npm run build
Sidenotes
Getting data
For performance purposes, you may want to get all the players data in one query. Then getEloOfPlayer
should read individual players Elo from parsed data.