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 seasonal leaderboards #11804

Merged
merged 27 commits into from
Feb 7, 2025
Merged

Add seasonal leaderboards #11804

merged 27 commits into from
Feb 7, 2025

Conversation

venix12
Copy link
Member

@venix12 venix12 commented Jan 20, 2025

Depends on #11768.
Part of #8736.

This adds per-season rankings to current seasons page, including seasonal total score (as of #11768) and assigned division display (calculation of which is part of this PR).

image


image_url column of divisions table isn't currently being utilized for purpose of the ranking display, but will be used for user profile division display in the future.

@venix12 venix12 changed the title Seasons leaderboards Add seasonal leaderboards Jan 20, 2025
@peppy
Copy link
Member

peppy commented Jan 24, 2025

@venix12 able to add some screenshots showing what we're adding here? 😄

@venix12
Copy link
Member Author

venix12 commented Jan 25, 2025

@venix12 able to add some screenshots showing what we're adding here? 😄

updated the opening message accordingly 👁️

{
return cache_remember_mutexed(
"divisions:{$this->id}",
$GLOBALS['cfg']['osu']['seasons']['divisions_cache_duration'],
Copy link
Member Author

@venix12 venix12 Jan 28, 2025

Choose a reason for hiding this comment

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

recently saw the duration being pulled from config/env in other places (tags) so just mimicked that, but wondering if this is actually needed here to begin with 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

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

no it's not. the other place involves some aggregation and stuff

Copy link
Collaborator

Choose a reason for hiding this comment

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

by "it's not" I mean the whole caching...

@nanaya
Copy link
Collaborator

nanaya commented Feb 5, 2025

what's this division/threshold/absolute threshold thing here? What's the difference between absolute and not?

@venix12
Copy link
Member Author

venix12 commented Feb 5, 2025

Divisions are tiers that are assigned to each of season's players based on their rank.

The divsisions (set per-season) are assigned for top x% of season players, therefore:

  • threshold is a (0-1) fraction meant to represent top amount of season's playerbase that should be assigned the division (e.g. 0.05, so 5%), it's stored in divisions table
  • absolute threshold is amount actual amount of players that will be assigned said division, aka. threshold * season players count, dynamically calculated based on current player count (e.g. Division with threshold=0.05 will be assigned to top 5 players of season with 100 participants)

threshold column should probably use decimal(4,3) or so instead of float now that i think about this 🤔

resources/views/seasons/_rankings_table.blade.php Outdated Show resolved Hide resolved
app/Models/Season.php Outdated Show resolved Hide resolved
public function divisionsWithAbsoluteThresholds(): array
{
$divisions = $this->divisions()->orderBy('threshold')->get();
$userCount = $this->userScores()->count();
Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe this should have forRanking filter just like the actual table

also the value is already queried by the pagination thing...

Comment on lines 72 to 74
@if (isset($currentDivision))
{{ $currentDivision['division']->name }}
@endif
Copy link
Collaborator

Choose a reason for hiding this comment

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

just use ?->name and skip the null check

Copy link
Member Author

Choose a reason for hiding this comment

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

that will throw error on trying to access division key on null, won't it? 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

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

oh I was trying it on a different thing before where the variable is assigned actual model. an ?? '' at the end works

resources/views/seasons/_rankings_table.blade.php Outdated Show resolved Hide resolved
resources/views/seasons/_rankings_table.blade.php Outdated Show resolved Hide resolved
app/Models/UserSeasonScoreAggregate.php Outdated Show resolved Hide resolved
@@ -0,0 +1,37 @@
<?php
Copy link
Collaborator

Choose a reason for hiding this comment

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

migration date needs an update

$table->integer('season_id')->unsigned();
$table->string('name');
$table->string('image_url');
$table->decimal('threshold', 4, 3);
Copy link
Collaborator

Choose a reason for hiding this comment

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

this results in string (including when casted as decimal) which isn't wanted. Operating on it properly is also a bit verbose. And then the result is rounded anyway...

A double is probably fine (or cast to double)

* @property string $image_url
* @property string $name
* @property int $season_id
* @property int $threshold
Copy link
Collaborator

Choose a reason for hiding this comment

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

not int

foreach ($divisions as $division) {
$divisionsWithMaxRanks[] = [
'division' => $division,
'max_rank' => $division->threshold * $userCount,
Copy link
Collaborator

Choose a reason for hiding this comment

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

can use an explicit rounding and casting to int

* @property string $image_url
* @property string $name
* @property int $season_id
* @property double $threshold
Copy link
Collaborator

Choose a reason for hiding this comment

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

it's all float in php

foreach ($divisions as $division) {
$divisionsWithMaxRanks[] = [
'division' => $division,
'max_rank' => get_int($division->threshold * $userCount),
Copy link
Collaborator

Choose a reason for hiding this comment

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

it works but it's not quite what get_int is for... ಠ_ಠ (it's more for validating unknown variable/string, not a known float)


<tr class="{{ class_with_modifiers('ranking-page-table__row', ['inactive' => !$score->user->isActive()]) }}">
<td class="ranking-page-table__column ranking-page-table__column--rank">
#{{ $rank }}
Copy link
Collaborator

Choose a reason for hiding this comment

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

can use i18n formatting

<tbody>
@foreach ($scores as $index => $score)
@php
$rank = $scores->firstItem() + $index;
Copy link
Collaborator

Choose a reason for hiding this comment

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

minor thing but maybe store the firstItem value beforehand

@@ -34,6 +34,10 @@ class="btn-osu-big btn-osu-big--rounded-thin"
<div class="js-react--seasons-show"></div>
@endsection

@section('scores')
@include('seasons._rankings_table', [$divisions, $scores])
Copy link
Collaborator

Choose a reason for hiding this comment

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

that's not how passing variable works. It should be ['var' => $thing] to access it as $var in the included view. It only seemed to work because all variables from current context are passed through.

@nanaya nanaya enabled auto-merge February 7, 2025 12:05
@nanaya nanaya merged commit 1e92697 into ppy:master Feb 7, 2025
3 checks passed
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.

3 participants