Skip to content

Credits

This class represents the credits that a user can use to purchase in-game merchandise.

Credits class that contains the credits for a user.

Source code in src/models/credits.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Credits:
    """Credits class that contains the credits for a user."""

    BASE_MULTIPLIER = 500
    """The base multiplier for calculating credits based on time taken."""

    BASE_CREDITS = 10
    """The base credits earned by speedrunning."""

    def __init__(self):
        self._stored_credits: int = 0

    def add_credits(self, amount: int) -> None:
        """Add credits to the user's account."""
        if amount < 0:
            raise ValueError("Amount to add must be non-negative.")
        self._stored_credits += amount
        logging.info(f"Added {amount} credits. New balance: {self._stored_credits}")

    def remove_credits(self, amount: int) -> None:
        """Remove credits from the user's account."""
        if amount < 0:
            raise ValueError("Amount to spend must be non-negative.")
        if amount > self._stored_credits:
            raise InsufficientCreditsError("Not enough credits to spend.")
        self._stored_credits -= amount
        logging.info(f"Removed {amount} credits. New balance: {self._stored_credits}")

    def update_credits(self, amount: int) -> None:
        """Update credits by adding (positive) or spending (negative)."""
        if amount >= 0:
            self.add_credits(amount)
        else:
            self.remove_credits(-amount)

    def get_credits(self) -> int:
        """Get the user's current credit balance."""
        return self._stored_credits

    def award_credits(self, seconds_taken: float, base_credits: int = 10, leaderboard: dict | None = None) -> int:
        """
        Calculates and adds the credits earned based on time taken.
        The faster the completion, the more credits earned.
        Optionally applies leaderboard bonuses based on rank.
        """
        if seconds_taken <= 0:
            raise ValueError("Time taken must be greater than zero.")

        multiplier = max(1, int(self.BASE_MULTIPLIER / seconds_taken))
        earned_credits = int(base_credits * multiplier)

        # Apply leaderboard bonus if leaderboard data is available
        if leaderboard:
            bonus_credits = Leaderboard.calculate_bonus(leaderboard, seconds_taken, earned_credits)
            earned_credits += bonus_credits
            logging.info(f"Leaderboard bonus applied: {bonus_credits} credits.")

        self.add_credits(earned_credits)
        logging.info(f"Awarded {earned_credits} credits for {seconds_taken} seconds taken. New balance: {self._stored_credits}")
        return earned_credits

BASE_CREDITS = 10 class-attribute instance-attribute

The base credits earned by speedrunning.

BASE_MULTIPLIER = 500 class-attribute instance-attribute

The base multiplier for calculating credits based on time taken.

add_credits(amount)

Add credits to the user's account.

Source code in src/models/credits.py
21
22
23
24
25
26
def add_credits(self, amount: int) -> None:
    """Add credits to the user's account."""
    if amount < 0:
        raise ValueError("Amount to add must be non-negative.")
    self._stored_credits += amount
    logging.info(f"Added {amount} credits. New balance: {self._stored_credits}")

award_credits(seconds_taken, base_credits=10, leaderboard=None)

Calculates and adds the credits earned based on time taken. The faster the completion, the more credits earned. Optionally applies leaderboard bonuses based on rank.

Source code in src/models/credits.py
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
def award_credits(self, seconds_taken: float, base_credits: int = 10, leaderboard: dict | None = None) -> int:
    """
    Calculates and adds the credits earned based on time taken.
    The faster the completion, the more credits earned.
    Optionally applies leaderboard bonuses based on rank.
    """
    if seconds_taken <= 0:
        raise ValueError("Time taken must be greater than zero.")

    multiplier = max(1, int(self.BASE_MULTIPLIER / seconds_taken))
    earned_credits = int(base_credits * multiplier)

    # Apply leaderboard bonus if leaderboard data is available
    if leaderboard:
        bonus_credits = Leaderboard.calculate_bonus(leaderboard, seconds_taken, earned_credits)
        earned_credits += bonus_credits
        logging.info(f"Leaderboard bonus applied: {bonus_credits} credits.")

    self.add_credits(earned_credits)
    logging.info(f"Awarded {earned_credits} credits for {seconds_taken} seconds taken. New balance: {self._stored_credits}")
    return earned_credits

get_credits()

Get the user's current credit balance.

Source code in src/models/credits.py
44
45
46
def get_credits(self) -> int:
    """Get the user's current credit balance."""
    return self._stored_credits

remove_credits(amount)

Remove credits from the user's account.

Source code in src/models/credits.py
28
29
30
31
32
33
34
35
def remove_credits(self, amount: int) -> None:
    """Remove credits from the user's account."""
    if amount < 0:
        raise ValueError("Amount to spend must be non-negative.")
    if amount > self._stored_credits:
        raise InsufficientCreditsError("Not enough credits to spend.")
    self._stored_credits -= amount
    logging.info(f"Removed {amount} credits. New balance: {self._stored_credits}")

update_credits(amount)

Update credits by adding (positive) or spending (negative).

Source code in src/models/credits.py
37
38
39
40
41
42
def update_credits(self, amount: int) -> None:
    """Update credits by adding (positive) or spending (negative)."""
    if amount >= 0:
        self.add_credits(amount)
    else:
        self.remove_credits(-amount)