Skip to content

Commit

Permalink
Cool Levels May 2024 Rebalance (#493)
Browse files Browse the repository at this point in the history
- Removes 15 CR bonus to new levels if they are reuploads
- Bumps the team pick bonus from 10 to 50
- Changes time required to fully decay from 3 months to 2 months
- Only reward 0.1 positive score per unique play (was 1 point before)
- Only apply 75% of the calculated negative score
- Adjust reward for hearts to 10 positive score
- Add a reward for a good ratio between plays and yays
  • Loading branch information
jvyden authored May 14, 2024
2 parents f43b0d4 + 3bc3fd9 commit 23c6a5a
Showing 1 changed file with 38 additions and 21 deletions.
59 changes: 38 additions & 21 deletions Refresh.GameServer/Workers/CoolLevelsWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ public void DoWork(Logger logger, IDataStore dataStore, GameDatabaseContext data

// Calculate positive & negative score separately so we don't run into issues with
// the multiplier having an opposite effect with the negative score as time passes
int positiveScore = CalculatePositiveScore(logger, level);
int negativeScore = CalculateNegativeScore(logger, level);
float positiveScore = CalculatePositiveScore(logger, level);
float negativeScore = CalculateNegativeScore(logger, level);

// Increase to tweak how little negative score gets affected by decay
const int negativeScoreMultiplier = 2;
const int negativeScoreDecayMultiplier = 2;

// Weigh everything with the multiplier and set a final score
float finalScore = (positiveScore * decayMultiplier) - (negativeScore * Math.Min(1.0f, decayMultiplier * negativeScoreMultiplier));
float finalScore = (positiveScore * decayMultiplier) - (negativeScore * Math.Min(1.0f, decayMultiplier * negativeScoreDecayMultiplier));

Log(logger, LogLevel.Debug, "Score for '{0}' ({1}) is {2}", level.Title, level.LevelId, finalScore);
scoresToSet.Add(level, finalScore);
Expand All @@ -81,7 +81,7 @@ private static void Log(Logger logger, LogLevel level, ReadOnlySpan<char> format

private static float CalculateLevelDecayMultiplier(Logger logger, long now, GameLevel level)
{
const int decayMonths = 3;
const int decayMonths = 2;
const int decaySeconds = decayMonths * 30 * 24 * 3600;
const float minimumMultiplier = 0.1f;

Expand All @@ -97,20 +97,34 @@ private static float CalculateLevelDecayMultiplier(Logger logger, long now, Game
return multiplier;
}

private static int CalculatePositiveScore(Logger logger, GameLevel level)
private static float CalculatePositiveScore(Logger logger, GameLevel level)
{
int score = 15; // Start levels off with a few points to prevent one dislike from bombing the level
const int positiveRatingPoints = 5;
const int uniquePlayPoints = 1;
const int heartPoints = 5;
const int trustedAuthorPoints = 5;
// Start levels off with a few points to prevent one dislike from bombing the level
// Don't apply this bonus to reuploads to discourage a flood of 15CR levels.
float score = level.IsReUpload ? 0 : 15;

const float positiveRatingPoints = 5;
const float uniquePlayPoints = 0.1f;
const float heartPoints = 10;
const float trustedAuthorPoints = 5;

if (level.TeamPicked)
score += 10;
score += 50;

int positiveRatings = level.Ratings.Count(r => r._RatingType == (int)RatingType.Yay);
int negativeRatings = level.Ratings.Count(r => r._RatingType == (int)RatingType.Boo);
int uniquePlays = level.UniquePlays.Count();

score += level.Ratings.Count(r => r._RatingType == (int)RatingType.Yay) * positiveRatingPoints;
score += level.UniquePlays.Count() * uniquePlayPoints;
score += positiveRatings * positiveRatingPoints;
score += uniquePlays * uniquePlayPoints;
score += level.FavouriteRelations.Count() * heartPoints;

// Reward for a good ratio between plays and yays
float ratingRatio = (positiveRatings - negativeRatings) / (float)uniquePlays;
if (ratingRatio > 0.5f)
{
score += positiveRatings * (positiveRatingPoints * ratingRatio);
}

if (level.Publisher?.Role == GameUserRole.Trusted)
score += trustedAuthorPoints;
Expand All @@ -119,13 +133,16 @@ private static int CalculatePositiveScore(Logger logger, GameLevel level)
return score;
}

private static int CalculateNegativeScore(Logger logger, GameLevel level)
private static float CalculateNegativeScore(Logger logger, GameLevel level)
{
int penalty = 0;
const int negativeRatingPenalty = 5;
const int noAuthorPenalty = 10;
const int restrictedAuthorPenalty = 50;
const int bannedAuthorPenalty = 100;
float penalty = 0;
const float negativeRatingPenalty = 5;
const float noAuthorPenalty = 10;
const float restrictedAuthorPenalty = 50;
const float bannedAuthorPenalty = 100;

// The percentage of how much penalty should be applied at the end of the calculation.
const float penaltyMultiplier = 0.75f;

penalty += level.Ratings.Count(r => r._RatingType == (int)RatingType.Boo) * negativeRatingPenalty;

Expand All @@ -137,6 +154,6 @@ private static int CalculateNegativeScore(Logger logger, GameLevel level)
penalty += bannedAuthorPenalty;

Log(logger, LogLevel.Trace, "negativeScore is {0}", penalty);
return penalty;
return penalty * penaltyMultiplier;
}
}

0 comments on commit 23c6a5a

Please sign in to comment.