About & ELO Calculation

How player ELO is computed on HLL Stats (detailed but concise).

Overview

ELO is updated per match. For each eligible round we compute a game score (gamepunkte) from your in-game stats, then adjust your ELO toward that score. The change is capped and scaled by opponent strength so that beating weaker teams gives less gain and losing to stronger teams gives less loss.

When is a match / player counted?

  • Match: Only rounds marked usable (min duration, KPM, max duration) and with at least 40 players.
  • Player: At least 15 minutes playtime; minimum activity (offense + defense) / time ≥ 0.08; at least 2 kills or deaths combined.

1. Game score (gamepunkte)

We normalize playtime to a reference length (5340 seconds ≈ 89 min) via time_factor = 5340 / your_time_seconds.

Active part

  • Kills: Weapon-adjusted kills (artillery 0.3×, tanks 0.5×, else 1×) × time_factor × 7.
  • Combat: Your combat score is weighted by a combat factor to reduce outliers without punishing support players. The ratio uses the same weapon-adjusted kill total as the kill line (not raw kills): combat / adjusted_kills. If adjusted_kills = 0, combat points = 0.
    • If factor ≤ 15: full weight (1.0).
    • From factor 15 → 35: linear drop to weight 0.2.
    • From 35 → 40: linear drop to 0. Above 40: 0 (e.g. tank-only commanders).
  • Active points = time_factor × weighted_combat + time_factor × (adjusted_kills × 7) (same as time_factor × (weighted_combat + adjusted_kills × 7)).

Passive part (support / defense / offense)

  • If (offense + defense) > 22 pts/min × your time, offense and defense are set to 0 (unrealistic values).
  • Support factor: 0.10 (default), 0.075 if support×time_factor ≥ 4000, 0.06 if ≥ 6000, 0.05 if ≥ 8000.
  • Passive = time_factor × (support × support_factor + defense × 0.15 + offense × 0.3).

Game score = active + passive.

2. ELO change (before opponent adjustment)

Raw change = (gamepunkte − current_elo) × base_multiplier. base_multiplier: 0.5 for your first 4 counted games (history rows with a non-null ELO), then 0.1.

Caps (so one match never swings too much)

  • If |raw_change| ≤ 600: use raw change.
  • If |raw_change| ≤ 1200: first 600 at 100%, rest at 50%.
  • If |raw_change| > 1200: first 600 at 100%, next 600 at 50%, remainder at 25%.

3. Opponent strength factor

Opponent strength per side uses the same formula as match-page team averages: 0.30×top5 + 0.30×top10 + 0.40×top20, only players with ≥ 15 min in that match, unknown players treated as 1000. Your opponents are the other side (Axis vs Allies). For the strength factor, ELO is taken before anyone in that match is updated (pre-match snapshot).

Strength factor (between 0.2 and 1.2)

  • Win vs stronger or equal opponents: factor = 1.0 (full gain).
  • Win vs weaker opponents: factor = 1000 / (1000 + (your_elo − opponent_avg)) (reduced gain).
  • Loss vs stronger opponents: factor = 1000 / (1000 + (opponent_avg − your_elo)) (reduced loss).
  • Loss vs weaker opponents: factor = 1.0 (no extra penalty). If your ELO ≥ 1500, factor is capped at 1.0.

Final ELO change = capped_change × strength_factor. New ELO = current_elo + final_change (rounded).

Match ELO (axis_avg / allies_avg)

On match and match-list pages we show axis_avg and allies_avg from the stored map_match_elo row: same weighted top-5/10/20 mix as above, but computed with each player’s ELO after that match has been applied (post-match snapshot). Tiers (e.g. Very Low, Normal, High, Super High) and imbalanced / highly imbalanced labels use these stored values and their difference (>100 / >200).

In short: strength factor for your ELO change uses pre-match side averages; match page team ELO bars use post-match averages.

Summary

ELO is a smoothed estimate of your performance: game score reflects kills (weapon-adjusted), combat (weighted using combat / adjusted_kills), and support/defense/offense. The update is damped by caps and by opponent strength (using pre-match side ELO). Displayed match team ELO uses post-match values. Processing is chronological so each step sees the correct history.

Full specification (same rules): backend/docs/ELO_AND_GAMEPUNKTE_CALCULATION.md