Opened 9 years ago

Last modified 5 years ago

#2516 new enhancement

Expand Rating System

Reported by: Josh Owned by:
Priority: Nice to Have Milestone: Backlog
Component: Multiplayer lobby Keywords:
Cc: Patch:

Description (last modified by OptimusShepard)

Currently only 1 vs. 1 games started through the multiplayer lobby are rated. This should at be expanded to support any grouping where the number of opponents are equal (eg. 2v2v2, 4v4, 1v1v1v1).

It would also be nice if the enable rating checkbox on the gamesetup page enabled/disabled itself based on a game's ratability.

Attachments (2)

gamereport-guide.txt (1.1 KB ) - added by Josh 9 years ago.
A brief guide on using the gamereport variable.
2v2.diff (9.7 KB ) - added by Jia Henry 8 years ago.
Hi again everyone. I've managed to find some more time to do some work on this patch. This the progress so far. IT doesn't work yet. When I test it , it gives me the following error (see comment below)

Download all attachments as: .zip

Change History (39)

comment:1 by scythetwirler, 9 years ago

Owner: changed from sycthetwirler to scythetwirler

It'd be nice if you spelled the owner as scythetwirler instead of sycthetwirler. :P

comment:2 by sanderd17, 9 years ago

Any player count without fixed teams should also be seen as a 1v1v1v..., as you can keep playing until there's only one winner.

comment:3 by scythetwirler, 9 years ago

I don't think we should rate games with more than two teams; there's too much randomness going on (who attacks who, who is closest to attack, so the team caught in the middle may have an inherent disadvantage) that doesn't really correlate to the skill of the players (which is what the rating should measure).

comment:4 by Jia Henry, 9 years ago

I agree with scythetwirler. Furthermore, teams with more than 2 players often result in the 2 players in the team that are on the edge of the map doing all the work and the player in the middle doing nothing. This is especially noticeable on the oasis maps where the 2nd player on the team is sandwiched between the first and 3rd player on the team and is unable to attack or expand due to being blocked by the oasis at the centre of the map and blocked by the 2 other players on his/her team

comment:5 by Jia Henry, 9 years ago

Keywords: patch review added
Owner: changed from scythetwirler to Jia Henry
Status: newassigned
Summary: Expand Rating System[PATCH] Expand Rating System

comment:6 by Jia Henry, 9 years ago

Component: Core engineMultiplayer lobby

comment:7 by Jia Henry, 9 years ago

I have attached a patch which I have made which should enable 2v2

However, it is untested, so someone will have to test it first.

comment:8 by scythetwirler, 9 years ago

Keywords: review removed

A couple comments:

  • Most of the function should be rewritten to handle arrays so we can avoid hard-coding so much.
  • The code is rather hard to follow for a somewhat simple concept; cleaning up the code would be nice.

ELO.py

  • Line 41: The rating inputs should be an array for each team, not inputted individually as separate variables, as it would make scaling for larger games a mess. This would change lines 58 & 59 as well.

XpartaMuPP.py:

  • You are missing colons after some of your for/if statements.
  • Don't reuse variables and move them to a higher scope if it is less confusing to just make them scoped to the loop itself. (Using i in two loops that aren't nested is fine, but moving i to the scope that encompasses both is not preferable).
  • Line 141: "i" should have a more descriptive name when you are using it to count players on a team.
  • Line 144: Using for in range() already increments, so the j += 1 is not necessary. This check could also be a lot simpler.
  • Line 148: Typo in comment.
  • Lines 179 onward: I feel that most of the patch around here can be much simpler.
  • Are you assuming that players[0] and players[1] are always on the same team? This may not be true.

comment:9 by Jia Henry, 9 years ago

OK, I'll improve it in the next few days

comment:10 by Corey, 9 years ago

extra: the i++ used on lines 233 239 262 and 266 is also not python and unneccessary for the same reason as j += 1. also line 175 is the syntax for a multiline comment but i can't see the other side of the comment. Also the for loops at the bottom? range(0,1) is just 0 in python so it runs once then stops, so is (2,3). what are you even trying to do with those? i cannot see any valid use for a for loop.

Last edited 9 years ago by Corey (previous) (diff)

by Josh, 9 years ago

Attachment: gamereport-guide.txt added

A brief guide on using the gamereport variable.

comment:11 by Jia Henry, 8 years ago

Keywords: review added

comment:12 by Josh, 8 years ago

Remove the "TODO: Team Games." on line 56 of ELO.py. Also, your patch of XpartaMuPP.py seems to be corrupted (see the "this hunk was shorter than expected" warning in the trac viewer). Your ELO.py changes look fine, but scythetwirler or alpha123 would be a better judge. Your changes to check that teams are balanced in XpartaMuPP.py seem to be logically convoluted. Try cleaning it up and avoid checking things more then you need. Fewer ifs would be nice. Sorry I can't be more helpful. You could also condense some of the loops you have at the end of rateGame. For example, concat all the winner names and ratings in one loop, all the loser names and ratings in a second loop, and construct 'message' after both loops.

That said, your patch has come a long way from it's first version. Thank you for putting in the effort and dedication.

comment:13 by Josh, 8 years ago

Keywords: review removed

comment:14 by Jia Henry, 8 years ago

Thanks Josh, I will edit it today

I'm not a python dev by the way. Just learning stuff as I go along :D

comment:15 by Jia Henry, 8 years ago

Keywords: review added

comment:16 by scythetwirler, 8 years ago

Keywords: review removed

Since we are almost certainly never going to find a way to rate uneven team games (such as 2v3s), winner and loser loops can be combined like you did in line 252 of XpartaMuPP.py.

There a couple of spacing issues (line 149, 251 of XpartaMuPP.py).

The range(x) function ranges from 0 to x-1 inclusive. Also, "if i < (len(losers) - 1): " should not be checked each time in that loop and the outer set of parenthesis is extraneous.

players_with_player1 is a rather ugly variable name, perhaps we can change it to something like "team_size"? This variable should be initialized before the loop.

Last edited 8 years ago by scythetwirler (previous) (diff)

comment:17 by Stan`, 8 years ago

Can't 2v3 be like 2 points for the team of two, if they win and, 1 point for each of the team of 3 if they win.

Other solution that could be used. Separate rating. A lot of games do that.

1v1 2v2 3v3 4v4 2v3 1v3 etc...

comment:18 by Jia Henry, 8 years ago

Keywords: review added

comment:19 by Josh, 8 years ago

Maybe my earlier comment wasn't clear enough, but I was hoping you could condense this:

    # Generate the message for the ratings
    message = "A rated game has ended. "
    for i in range(len(winners)):
      message = message + winners_names[i]
      if i < (len(winners) - 2):
        message = message + ", "
      elif i == (len(winners) - 2):
        message = message + " and "
    message = message + "won against "
    for i in range(len(losers)):
      message = message + losers_names[i]
      if i < (len(losers) - 2):
        message = message + ", "
      elif i == (len(losers) - 2):
        message = message + " and "
    message = message + ". Rating Adjustment: "
    for i in range(len(winners)):
      message = message + "%s (%s -> %s)" %(winners_names[i], winners_ratings[i], winners_ratings[i] + winners_ratings_adjustments[i])
      if i < (len(winners) - 2):
        message = message + ", "
      elif i == (len(winners) - 2):
        message = message + " and "
    message = message + "won against "
    for i in range(len(losers)):
      message = message + "%s (%s -> %s)" %(losers_names[i], losers_ratings[i], losers_ratings[i] + losers_ratings_adjustments[i])
      if i < (len(losers) - 2):
        message = message + ", "
      elif i == (len(losers) - 2):
        message = message + " and "
    self.lastRated = message

And make it into something more like this:

    winnerNameStr = ""
    winnerRatingStr = ""
    loserNameStr = ""
    loserRatingStr = ""
    # Concat winner data together for message
    for i in range(len(winners)):
      # Put an 'and' before the last winner listed.
      if i == len(winners_names) - 1:
        # Only put a comma before the 'and' if more than two winners are listed.
        if len(winners) > 2:
          winnerNameStr += ","
          winnerRatingStr += ","
        winnerNameStr += " and "
        winnerRatingStr += " and "
      elif i != 0:
        winnerNameStr += ", "
        winnerRatingStr += ", "
      winnerNameStr += winners_names[i]
      winnerRatingStr += "%s (%s -> %s)" %(winners_names[i], winners_ratings[i], winners_ratings[i] + winners_ratings_adjustments[i])
    # Concat loser data together for message
    for i in range(len(losers)):
      # Put an 'and' before the last loser listed.
      if i == len(losers_names) - 1:
        # Only put a comma before the 'and' if more than two losers are listed.
        if len(losers) > 2:
          loserNameStr += ","
          loserRatingStr += ","
        loserNameStr += " and "
        loserRatingStr += " and "
      elif i != 0:
        loserNameStr += ", "
        loserRatingStr += ", "
      loserNameStr += losers_names[i]
      loserRatingStr += "%s (%s -> %s)" %(losers_names[i], losers_ratings[i], losers_ratings[i] + losers_ratings_adjustments[i])

    # Construct message
    self.lastRated = "A rated game has ended. " + winnerNameStr + "won against" + loserNameStr + ". Rating Adjustments: " + winnerRatingStr + "won aginst " + loserRatingStr + "."

(The above is tested and also adds the standard oxford comma along with simplifying the message. Feel free to copy-paste.)

comment:20 by Josh, 8 years ago

Keywords: review removed

comment:21 by leper, 8 years ago

Josh: Or just use join and don't care for the and. (Or just join all but the last one and add it that way)

in reply to:  21 comment:22 by Josh, 8 years ago

Replying to leper:

Josh: Or just use join and don't care for the and. (Or just join all but the last one and add it that way)

Join wouldn't work for the ratings string and the extra logic to handle the 'and' in the names string would balance out all the improvement of using join.

comment:23 by leper, 8 years ago

It wouldn't. For the rating strings use map first, then join. Should make one of the loops roughly 3 lines, which is still better than even your improved version.

comment:24 by Jia Henry, 8 years ago

Keywords: review added

comment:25 by leper, 8 years ago

Keywords: review removed

Lines 221-224 can be deleted. [0:something] is the same as [:something]. Check if the code still works with 1vs1s, if it doesn't (which looks like it is the case) use an inline if (roughly a ternary operator) to add the " and " only if it is needed.

Lines 198-218 could be improved with some map calls too.

Lines 183-191 can be shortened with two calls to filter. (Use a local var to find the team of a winner (maybe using next() (as in next(game.player_info[i].team for i in game.players if i == game.winner)))

Lines 151-152: fix the indentation, also make that a real comment, not an explanation of what the code already says; The code above that if can probably be improved (shortened/cleaned up) by removing the special case for 1vs1s.

in reply to:  25 comment:26 by Jia Henry, 8 years ago

I don't understand why, but my code suddenly stopped working recently. I've debugged it by adding in some print statements (which are not in the diff I've uploaded) and it looks like pyro's not sending data to the bot, but I can't work out why.

Last edited 8 years ago by Jia Henry (previous) (diff)

comment:27 by Timothy Hamlett, 8 years ago

Cc: tjh.hts@… added

comment:28 by Timothy Hamlett, 8 years ago

could it be in the code that you shortened?

comment:29 by Jia Henry, 8 years ago

I've debugged it further and it looks like in non 1v1s, pyrogenesis is telling the bot in the gamereport that playerStates are "active" so the lobby bot thinks the game is still in progress. I can't understand why though.

comment:30 by Itms, 8 years ago

Milestone: Alpha 17Alpha 18

Based on an IRC discussion with Henry, the new bot is to be taken care of by someone else very soon. However, the bot will not be ready for A17, so I push this back.

If I'm not mistaken, the bot can be updated even if there is no release, as far as code changes are not necessary.

comment:31 by Jia Henry, 8 years ago

Well, I'm back n school now so I don't have much time to work on it so that's why I said that Itms.

But anyway, I already worked out what needs to be done but I don't have enough python skills or the time to code it.

Here's what needs to be done:

Currently, pyrogenesis only submits a game report if someone's playerState that instance of pyrogenesis is not an observer and the game has not ended has changed and the lobby bot only rates a game if all the players have submitted a game report.

This doesn't work for rated team games. I will illustrate this in the scenario below:

So, let's suppose in a 2v2 where players 1&2 are on the same team and players 3&4 are on the same team:

  1. Player 1 is defeated. This means that 4 game reports are submitted as none of the players are observers at the time.
  1. Player 2 is defeated. This means that 3 game reports are submitted as may player 1 is an observer or he may have already left the game.

This results in pyrogenesis not rating the game as the number of gamereports submitted does not equal the player number

This all needs to be replaced with new code so that any new gamereports for a game are appended to the old gamereports of that game.

Good luck to anybody who wishes to work on this patch :)

comment:32 by leper, 8 years ago

Cc: tjh.hts@… removed
Milestone: Alpha 18Backlog

comment:33 by scythetwirler, 8 years ago

Owner: Jia Henry removed
Status: assignednew

by Jia Henry, 8 years ago

Attachment: 2v2.diff added

Hi again everyone. I've managed to find some more time to do some work on this patch. This the progress so far. IT doesn't work yet. When I test it , it gives me the following error (see comment below)

comment:34 by Jia Henry, 8 years ago

Traceback (most recent call last):

File "XpartaMuPP.py", line 753, in iqhandler

self.reportManager.addReport(iqfrom, iqgamereportgame)

File "XpartaMuPP.py", line 401, in addReport

self.checkFull()

File "XpartaMuPP.py", line 458, in checkFull

self.leaderboard.addAndRateGame(self.expandReport(self.interimReportTracker[i], self.interimJIDTracker[i]))

File "XpartaMuPP.py", line 432, in expandReport

if self.processedGameReportplayerStates[player] == "active" and inProcessGameReportplayerStates[player] != "active":

KeyError: <LobbyRanking.Player object at 0x7f5dc56aa4e0>

comment:35 by Stan`, 8 years ago

Keywords: patch removed
Summary: [PATCH] Expand Rating SystemExpand Rating System

comment:36 by scythetwirler, 6 years ago

Priority: Must HaveNice to Have

Making this abuse-proof is very difficult.

comment:37 by OptimusShepard, 5 years ago

Description: modified (diff)

I think there is a really need for multiplayer ratings. The singleplayer ratings doesn't say much about your multiplayer abilitys. So here is my "simple" idea. Rating only for games with two teams (independently if 2vs2 or 1vs3 or other constellations):

  • add up all ratings of every team
  • so you have two ratings, which are also depending on how much member a team have
  • take this two ratings and use the same function as in 1vs1
  • add this resulting difference to every member of the teams

So not every game could be fair rated, but in the average it should be balanced.

Note: See TracTickets for help on using tickets.