Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user season score calculation workflow #11768

Open
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

venix12
Copy link
Member

@venix12 venix12 commented Jan 2, 2025

Part of #8736.

Serving as a base for implementation of seasonal rankings in nearing feature.

This mimics the Beatmap Spotlights seasonal rankings calculation process that used to be done via an external script.

Also adds an artisan command for score recalculating.

Tried to optimize the calculation process as much as possible, any further potential improvements on that matter would be vastly appreciated. 🤔

How does this work?

Rooms

  1. The seasons are designed as a series of few (currently: three) playlists that are usually labeled by consecutive letters of alphabet (A, B, C).

  2. Each of the playlists is ran twice over a course of the season. For the sake of this implementation, the rooms of the first run of the playlists are referred to as "parent rooms", while the rooms of the second run are called "children rooms".

This PR adds group_indicator to the season_rooms table, to group parent and children rooms together.

Score calculation

Total (user) season score is sum of best playlist total scores achieved throughout the season, with added factor-based weighting.

  1. Total scores of a each playlist are compared between the parent and child rooms, with higher being taken for total season score calculation.

  2. Said scores are sorted from highest to lowest, and season-specified factors are being applied in descending order to each of them (e.g. 1.0, 0.75, 0.5). This results in final total season score.

This PR adds the following:

  • user_season_score_aggregates table, total_score of which is calculated using related model calculate() function, that is called whenever user places a score on related season's room.
  • score_factors field on seasons table that stores factors used for total season score calculation.

Example user total season score calculation

Let's say a user achieves following scores during the six playlists of the season:

playlist score (parent) score (child)
A 10 12
B 20 15
C 5 40

The season's score factors are set to following: 1, 0.75, 0.5.

Playlist final scores are being sorted in descending order, resulting in following values: 40, 20, 12. The final season score calculation goes as below:

40 * 1 + 20 * 0.75 + 12 * 0.5 = 40 + 15 + 6 = 61

The total season score is 61. That value would be used for sake of placing user in seasonal leaderboard.

@venix12 venix12 changed the title Add season user score calculation workflow Add user season score calculation workflow Jan 3, 2025
Copy link
Member

@cl8n cl8n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly commenting on the db structure, I didn't review all the code too closely

app/Models/Season.php Outdated Show resolved Hide resolved

/**
* @property int $id
* @property float $factor
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also want to question whether the concept of "factors" here is important to the score calculation because it seems a little complicated to me (as a player) and I can't imagine what would cause you to tune the factors individually. would something more straightforward like how total pp is weighted not work?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

factors should really be consistent across the seasons these days, though used to be changed in the past (e.g. i believe 4-playlist format we had before used a different set than what we use now), so this is mostly for backwards compatibility i think

app/Models/UserSeasonScore.php Outdated Show resolved Hide resolved
$factors = $this->season->scoreFactorsOrderedForCalculation();
$parentRooms = $this->season->rooms->where('parent_id', null);

if ($parentRooms->count() > count($factors)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like these have to be equal?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

having too many factors shouldn't be an issue when they are ordered in descending order for calculation, it is handy to just set them all per-season without having to update with every new playlist launch 🤔

app/Models/UserSeasonScore.php Outdated Show resolved Hide resolved
app/Models/Multiplayer/Room.php Outdated Show resolved Hide resolved
app/Models/UserSeasonScore.php Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants