Logo

Randomu' Oltenesc

ARAM Mayhem
Sync App (Windows)

Cum se calculeaza ratingul

Scor Compozit (calculat in timp real)

Rating-ul se calculeaza din datele raw ale meciului, comparat cu toti participantii prin rank-normalizare. Formula e role-agnostic — tank, support, ADC sau fighter sunt evaluate echitabil. Nu exista bonus/penalizare pentru victorie/infrangere — scopul e masurarea contributiei individuale pentru echilibrarea echipelor.

Impact 60%
  • 40% Kill Participation (KP) — (K+A) / Team Kills
  • 35% Role Performance — se ia cea mai buna metrica din 3 roluri:
    • Damage: Damage Share × 5 (cat % din damage-ul echipei ai facut)
    • Tank: Tank Share × 5 (cat % din damage taken + mitigated al echipei)
    • Support: Healing + CC Score × 100, rank-normalizat
  • 25% Kill/Assist Share — (K+A) / Team (K+A)
Supravietuire 15%
  • KDA Ratio: (K+A) / (D+1), rank-normalizat in meci
  • Ponderea redusa (15%) ca sa nu penalizeze tankii care fac engage
Eficienta 25%
  • max(Damage/Gold, CC/Gold), rank-normalizat
  • Damage dealers primesc credit pentru DPG, tankii/supportii pentru CC/Gold

Formula

Composite = 0.60×Impact + 0.15×Supravietuire + 0.25×Eficienta

Se aplica o functie de stretch (exponent 0.35) pentru a mari diferentele intre jucatori:

Rating = 1.0 + 9.0 × stretch(Composite) + Bonusuri

Rank-normalizare

Fiecare metrica se compara cu toti participantii meciului prin ranking (cel mai bun = 1.0, cel mai slab = 0.0). In meciuri mici (2-4 jucatori) se aplica damping care trage scorurile catre 0.5 pentru a evita extremele. Asta inseamna ca un meci de 3v3 nu va produce rating-uri la fel de polarizate ca un 5v5.

Bonusuri & Penalizari

Se aplica dupa calculul compozit. Unele sunt scalate cu numarul de jucatori (meciuri mici = penalizari mai blande).

Bonusuri
  • +0.60 "The Carry" — Rank 1 Damage SI Rank 1 KP (5+ jucatori)
  • +0.40 "Smart Player" — Cele mai putine deaths + KP > 50% (5+ jucatori)
  • +0.40 "The Frontline" — Most damage taken + KP > 40% — recompenseaza tankii care fac engage si participa activ
Penalizari
  • -1.50 "The Passenger" — KP < 25% SI bottom damage (scalat cu nr. jucatori). Protejat: supportii cu healing/CC in top 2 NU primesc aceasta penalizare
  • -0.70 "Gold Sink" — Rank 1 Gold dar bottom damage (5+ jucatori). Protejat: supportii cu healing/CC in top 2
  • -0.50 "Dead Weight" — Cele mai multe deaths + KP < 35% (scalat cu nr. jucatori)

Ce NU afecteaza ratingul

  • Victoria/Infrangerea — nu exista bonus de win/loss. Rating-ul masoara contributia individuala, nu rezultatul meciului. Asta previne feedback loop-ul unde jucatorii cu rating mare ajung in echipe mai bune, castiga, si primesc rating si mai mare.

De ce e fair pentru orice rol?

  • Tank — primeste credit prin Tank Share (Impact), bonus "The Frontline", si Survival redus la 15% ca sa nu fie penalizat pentru deaths inevitabile din engage
  • Support — primeste credit prin Support Score (healing + CC), protejat de penalizarile "Passenger" si "Gold Sink" daca are healing/CC ridicat
  • ADC/Mage — primeste credit prin Damage Share si Damage/Gold efficiency
  • Fighter/Bruiser — beneficiaza de mix: damage share, tank share, si KP ridicat

Rating overall

Rating-ul overall este media aritmetica a ultimelor 10 meciuri, calculata in timp real din datele raw. La rating egal, se departajeaza dupa Win Rate (L10).

Codul sursa

// ── Rank-normalizare ──
function rankNormalize(values) {
  const n = values.length;
  if (n <= 1) return values.map(() => 0.5);
  const indexed = values.map((v, i) => ({ v, i }));
  indexed.sort((a, b) => b.v - a.v);
  const scores = new Array(n);
  // damping: N=2 → 0.4, N=3 → 0.6, N=5 → 0.8, N>=8 → ~1.0
  const damping = Math.min(1, 1 - 2 / (n + 1));
  for (let rank = 0; rank < n; rank++) {
    const raw = 1 - (rank / (n - 1));
    scores[indexed[rank].i] = 0.5 + (raw - 0.5) * damping;
  }
  return scores;
}

// ── Stretch + Rating ──
function stretchFromCenter(value, exp) {
  if (value < 0.5) return 0.5 - Math.pow((0.5 - value) / 0.5, exp) * 0.5;
  return 0.5 + Math.pow((value - 0.5) / 0.5, exp) * 0.5;
}

function compositeToRating(composite, bonusAdj) {
  const stretched = stretchFromCenter(Math.max(0, Math.min(1, composite)), 0.35);
  return Math.max(1.0, Math.min(10.0, Math.round((1.0 + 9.0 * stretched + bonusAdj) * 100) / 100));
}

// ── Raw metrics per participant ──
const raw = participants.map(p => ({
  kp:              Math.min(1, (p.kills + p.assists) / teamKills),
  damage_share:    p.damage / teamDamage,
  tank_share:      (p.damage_taken + p.self_mitigated) / teamTakenMit,
  support_metric:  p.healing + p.cc_score * 100,
  ka_share:        (p.kills + p.assists) / teamKA,
  kda:             (p.kills + p.assists) / (p.deaths + 1),
  damage_per_gold: p.damage / p.gold,
  cc_per_gold:     p.cc_score / p.gold,
}));

// ── Rank-normalize all metrics ──
const rSupport     = rankNormalize(raw.map(r => r.support_metric));
const rKda         = rankNormalize(raw.map(r => r.kda));
const rDmgPerGold  = rankNormalize(raw.map(r => r.damage_per_gold));
const rCcPerGold   = rankNormalize(raw.map(r => r.cc_per_gold));
const rDamage      = rankNormalize(raw.map(r => r.damage));
const rGold        = rankNormalize(raw.map(r => r.gold));
const rDeaths      = rankNormalize(raw.map(r => -r.deaths));
const rKp          = rankNormalize(raw.map(r => r.kp));
const rHealing     = rankNormalize(raw.map(r => r.support_metric));
const rDamageTaken = rankNormalize(raw.map(r => r.damage_taken + r.self_mitigated));

// ═══ 1. IMPACT (60%) ═══
const rolePerf = Math.min(1, Math.max(
  r.damage_share * 5,   // Damage dealer
  r.tank_share * 5,     // Tank
  rSupport[i]           // Support (rank-normalized)
));
const impact = 0.40 * r.kp + 0.35 * rolePerf + 0.25 * r.ka_share;

// ═══ 2. SURVIVAL (15%) ═══
const survival = rKda[i];

// ═══ 3. EFFICIENCY (25%) ═══
const efficiency = Math.max(rDmgPerGold[i], rCcPerGold[i]);

// ═══ Composite ═══
let composite = 0.60 * impact + 0.15 * survival + 0.25 * efficiency;

// ═══ Bonusuri & Penalizari ═══
const bScale = Math.min(1, (n - 1) / 9);
const isHealer = rHealing[i] >= 0.75;  // top 2 support

if (rDamage[i] >= 0.99 && rKp[i] >= 0.99)            bonus += 0.60;  // The Carry
if (rDeaths[i] >= 0.99 && r.kp > 0.50)               bonus += 0.40;  // Smart Player
if (rDamageTaken[i] >= 0.99 && r.kp > 0.40)          bonus += 0.40;  // The Frontline
if (r.kp < 0.25 && rDamage[i] <= 0.15 && !isHealer)  bonus -= 1.50;  // The Passenger
if (rGold[i] >= 0.99 && rDamage[i] <= 0.25 && !isHealer) bonus -= 0.70; // Gold Sink
if (rDeaths[i] <= 0.15 && r.kp < 0.35)               bonus -= 0.50;  // Dead Weight

// ═══ Final Rating (1-10) ═══
rating = compositeToRating(composite, bonus);
Se incarca...