Defrag-racing / defrag-racing-project

https://defrag.racing/
GNU Affero General Public License v3.0
4 stars 2 forks source link

Add rankings #49

Open michalwitwicki opened 2 months ago

michalwitwicki commented 2 months ago

This PR is still a Work In Progress

This PR introduces a system to calculate player ratings using Python and the Polars framework. Polars is written in Rust and is highly efficient due to its parallelized computations, making it very fast. On my 2015 laptop (4 threads @ 2.3GHz, 8GB RAM), the calculations take about 1.2 seconds. However, one downside is the time it takes to upload the computed table into MySQL, which takes around 30 seconds on my machine.

Currently, the Python script runs every two minutes, but this interval can be easily adjusted.

The final player_ratings are calculated separately for each physics + mode category through three stages:

  1. Calculating the map_score for each record in the database
  2. Calculating the weighted_map_scores for each record
  3. Summing up the weighted_map_scores for each player

The algorithm used to calculate map_score is adapted from Xonotic DWC:

map_score = 1000 * (time_of_the_fastest_competitor / time) * 0.988 ^ (pos - 1)

I’ve made minor adjustments to better fit our environment, which includes many maps.

To calculate weighted_map_scores, I first sort the map_scores for each player in each physics + mode category and assign an index to each. The highest map_score is assigned index 1, the next one index 2, and so on. The weighted_map_scores are calculated using the following formula:

weighted_map_score = map_score * (0.98 ^ (map_score_index - 1))

The lower a map_score is, the less impact it has on the final player_rating so players won't be discouraged to submit new records out of fear lowering their rankings.

The player's final rating is determined by summing up all weighted_map_scores within the relevant category. Maps with fewer than 5 records are not factored into the player_rating.

Please note that the above formulas are placeholders and could be improved or even replaced. I welcome any suggestions! I know @neyoneit wanted to try this system, but I don’t fully understand it. If someone could translate it into pseudocode, I may be able to implement it.

Additionally, there are a lot of maps that should not contribute to player_ratings at all, for various reasons, such as:

  1. The map is bugged
  2. It doesn’t test actual defrag skills
  3. It contains inappropriate content
  4. Completion time is heavily dependent on luck
  5. The map is excessively long, etc

A system for excluding such maps is already implemented, but we first need to identify which maps fall into these categories.

What Is left to do in this PR:

  1. Adjust, modify or replace calculations formulas
  2. Add some simple sorting and filtering to the rankings list
  3. Make rankings list look better
  4. Define list of banned maps (if we ever will have "tagging maps" system, this could be easily managed there
crabcrabcam commented 2 months ago

https://gitlab.com/exe.pub/luffa/-/blob/master/src/models/ladders.rs?ref_type=heads#L353

That's how the xdf.gg/rating system is implimented in Rust. It's a much better system for this sort of thing (I've used the XDWC system on a different game, and the scores are wild unless people have a similar number of map finishes)