Skip to main content

Overview

The Olympiad is L2J Mobius’s competitive PvP system featuring an ELO-based rating system, seasonal competitions, and hero selection. Players compete in class-based or non-class battles to earn points, climb divisions, and potentially become Heroes.
The Olympiad system uses a sophisticated ELO ranking algorithm with anti-feeding protections and soft season resets to maintain competitive integrity.

ELO Rating System

Formula

The ELO system updates ratings after each match using the standard formula:
ELO_new = ELO_current + K × (ActualResult - ExpectedResult)
Where:
  • K Factor: Volatility constant (default: 32)
  • ActualResult: 1.0 for win, 0.0 for loss, 0.5 for draw
  • ExpectedResult: Calculated as:
E_A = 1 / (1 + 10^((ELO_B - ELO_A) / 400))
Source: Olympiad.java:14-21 (from ELO_ANALYSIS.md)

Division System

Players are ranked into 5 divisions based on their ELO rating:
DivisionELO RangeColor
Bronze< 1100Gray (0x808080)
Silver1100-1299White (0xFFFFFF)
Gold1300-1499Yellow (0xFFFF00)
Platinum1500-1799Cyan (0x00FFFF)
Diamond1800+Magenta (0xFF00FF)
Implementation: Olympiad.java:154-176
public static String getDivision(int elo) {
    if (elo < 1100) return DIV_BRONZE;
    if (elo < 1300) return DIV_SILVER;
    if (elo < 1500) return DIV_GOLD;
    if (elo < 1800) return DIV_PLATINUM;
    return DIV_DIAMOND;
}

Competition Mechanics

Match Types

  • Requires minimum 5 participants of same class
  • Entry cost: 3 Olympiad Points
  • Fair matchmaking within class restrictions
  • Higher rewards for class victories
  • Requires minimum 9 participants total
  • Entry cost: 5 Olympiad Points
  • Cross-class competition
  • ELO-based matchmaking

Registration Restrictions

Players cannot register if:
  • Not in base class (subclass prohibited)
  • Inventory 80%+ full
  • Less than 10 minutes until competition ends
  • Already registered or participating in events
  • Below minimum point requirements
Source: Olympiad.java:531-553

Anti-Feeding Protection

If the ELO difference between participants exceeds 400 points (configurable via OLYMPIAD_ELO_MAX_GAP), the match awards no ELO points. This prevents high-ranked players from exploiting low-ranked accounts.
Implementation:
if (Math.abs(player1Elo - player2Elo) > OLYMPIAD_ELO_MAX_GAP) {
    // Match proceeds but no ELO changes
    return;
}

Season System

Season Duration

Seasons consist of multiple cycles (default: 3 cycles per season):
  • Each cycle lasts approximately 1 month
  • Competition period alternates with validation period
  • Weekly point bonuses during active cycles

Soft Reset Mechanics

At season end, ELO ratings undergo soft reset rather than full reset:
ELO_new = 1000 + (ELO_old - 1000) × SoftResetMultiplier
Default SoftResetMultiplier: 0.5 Benefits:
  • Maintains relative skill hierarchy
  • Reduces extreme rating gaps
  • Prevents unfair matchmaking at season start
Source: Olympiad.java:1575-1582

Season Rewards

Rewards are distributed based on final division:
DivisionDefault RewardCount
BronzeGate Pass (6656)100
SilverGate Pass (6656)250
GoldGate Pass (6656)500
PlatinumGate Pass (6656)1000
DiamondGate Pass (6656)2000
Rewards are configurable via config/Olympiad.ini season reward settings.

Hero Selection

Eligibility Requirements

  • Minimum 9 competitions completed
  • At least 1 competition won
  • Highest Olympiad points in class

Selection Process

  1. System queries top performer per class
  2. Ties broken by:
    • Total competitions done (more is better)
    • Competitions won (more is better)
  3. Heroes selected during validation period
  4. Special handling for Soul Hound classes (132/133 compete as one)
Source: Olympiad.java:1197-1330

Configuration

Core Settings (config/Olympiad.ini)

# ELO System
OlympiadEloInitialValue = 1000
OlympiadEloKFactor = 32
OlympiadEloMaxGap = 400
OlympiadEloAnnounceThreshold = 1500
OlympiadEloRewardMultiplier = 1.0

# Season Settings
OlympiadSeasonDuration = 3
OlympiadSeasonSoftResetMultiplier = 0.5

# Competition Settings
OlympiadStartPoints = 18
OlympiadWeeklyPoints = 3
OlympiadMaxPoints = 10
OlympiadClassedParticipants = 5
OlympiadNonClassedParticipants = 9

# Timing
OlympiadStartTime = 18
OlympiadCPeriod = 21600000  # 6 hours in ms
OlympiadBattle = 360000     # 6 minutes

Database Schema

olympiad_nobles table:
CREATE TABLE olympiad_nobles (
    charId INT,
    class_id INT,
    olympiad_points INT,
    competitions_done INT,
    competitions_won INT,
    competitions_lost INT,
    competitions_drawn INT,
    elo INT,
    PRIMARY KEY (charId)
);
olympiad_seasons_history table: Stores historical data per season for tracking progression.

Competition Schedule

Period Types

  1. Competition Period: Active battles (default: 1 month)
  2. Validation Period: Hero selection (default: 24 hours)
  3. Competition Hours: Daily battle window (default: 6 hours starting 18:00)

Weekly Bonuses

Players receive 3 Olympiad Points automatically each week during competition period:
protected void addWeeklyPoints() {
    if (_period == 1) return;
    
    for (StatSet nobleInfo : NOBLES.values()) {
        nobleInfo.set(POINTS, 
            MathUtil.clamp(nobleInfo.getInt(POINTS, 0) + WEEKLY_POINTS, 0,
                (nobleInfo.getInt(COMP_DONE, 0) * OLYMPIAD_MAX_POINTS) 
                + (OLYMPIAD_WEEKLY_POINTS * 4)));
    }
}
Source: Olympiad.java:988-999

Thread Safety

Critical Fix Applied: The original implementation had a race condition in registerNoble(). The fix uses computeIfAbsent() for atomic map operations:
// Fixed implementation (line 602)
_classBasedRegisters.computeIfAbsent(
    noble.getPlayerClass().getId(), 
    k -> Collections.synchronizedList(new ArrayList<>())
).add(noble);
Issues Resolved:
  • Prevented concurrent registration data loss
  • Eliminated ConcurrentModificationException during matchmaking
  • Ensured thread-safe participant list iteration
Source: ELO_ANALYSIS.md lines 60-75

FAQ

The system attempts to match players with similar ELO ratings. If the difference exceeds 400 points, the match awards no ELO changes to prevent exploitation.
Yes, Hero status is recalculated each validation period. You must maintain top performance in your class to retain it.
Disconnection counts as a loss. Your opponent receives a win, and you lose ELO points accordingly.
Rewards are based on your final division at season end. The amount scales with division tier (Bronze → Diamond).

References

  • Olympiad.java - Core system implementation
  • OlympiadConfig.java - Configuration loader
  • OlympiadGame.java - Match execution logic
  • ELO_ANALYSIS.md - Technical deep-dive on rating system

Build docs developers (and LLMs) love