Ooglely / pugBot

Discord bot to run TF2 pick up games | pugbot.tf
https://pugbot.tf
22 stars 1 forks source link

New ELO System #16

Closed amos-cha closed 10 months ago

amos-cha commented 1 year ago

Current PUG ELO system is based on RGL tags/divisions. This causes major issues for generation as "fair" gens are almost never fair as it does not account for players who only pug (no "comp" experience) or players who roster ride or teams who joined a division that they don't belong in (high or low).

Current investigations

TF2 is an incredibly team based game. However, it is not to discount the fact that teams can be subject to hard carries by high impact classes or class specialists. My first thought was that a game like OW2's elo system may be able to account for discrepancy. However, the new elo system does not actually put much weight on individual performance.

My mental solution: which will still take time to develop and structure before actualization is a combination of: UGC's MGE elo system

OW1's Elo system

@Ooglely any thoughts?

Ooglely commented 1 year ago

My idea was to first use the old TF2CC elo system, which was calculated like this:

def _probability(self, team1_avg_elo: float, team2_avg_elo: float) -> float:
    # probability that team2 would win against team1
    return 1 / (1 + pow(10, (team1_avg_elo - team2_avg_elo) / 300))

async def get_team_elo_changes(self, avg_red_elo: float, avg_blu_elo: float) -> tuple[int, int]:
    base_elo_change = 40
    red_rounds_ratio = self.red_team.score / self.total_rounds
    blu_rounds_ratio = self.blue_team.score / self.total_rounds
    red_team_prob = self._probability(avg_blu_elo, avg_red_elo)
    blu_team_prob = self._probability(avg_red_elo, avg_blu_elo)
    #f"red_rounds_ratio: {red_rounds_ratio}")
    #LOG.debug(f"blu_rounds_ratio: {blu_rounds_ratio}")
    #LOG.debug(f"red_team_prob: {red_team_prob}")
    #LOG.debug(f"blu_team_prob: {blu_team_prob}")

    if self.length < 15 * 60 and (red_rounds_ratio == 0 or blu_rounds_ratio == 0):
        base_elo_change *= 1.2
    #LOG.debug(f"base_elo_change: {base_elo_change}")

    return (
        int(base_elo_change * (red_rounds_ratio - red_team_prob)),
        int(base_elo_change * (blu_rounds_ratio - blu_team_prob))
    )

It's not perfect but it basically does the job that a MGE-like ELO system would do. In the future I would want to have a rating system for players performances kind of like HLTV.org has, but that would be a huge project that would take a while to do.

amos-cha commented 1 year ago

im actually not too familiar with the old elo system. The logic seems to flow kind of like a betting system which makes sense. I think we can start with that and see if we can get some logs.tf api integration for further statistical calculations?