Achievements ~ Final Report 2025 - uchicago-cs/chigame GitHub Wiki

CMSC 22000 Final Report

Quarter: Spring 2025

Feature: Achievements

Design and Implementation

An achievement is a trophy awarded to a player for their dedication and skills in a game. The achievements feature, which is a completely new feature to Chigame, allows users to earn achievements from games when certain conditions are met. These conditions are set by the game developers, so every game has its own unique set of achievements, which users can earn and display on their profiles. Our implementation of the achievements feature consists of the front-end design (the way achievements are displayed on users’ profiles) and back-end logic (models and views).

Frontend design

The frontend implementation was written in HTML, JavaScript, and CSS. It includes a dedicated user achievements page that displays key user attributes—such as avatar, stats, and join date—alongside their earned and in-progress achievements. Achievements are organized by game and grouped into visually distinct cards. Each group presents the achievements available in that game, showing their title, description, progress, and rarity level, which is represented using color-coded trophy icons ranging from common to precious. Each achievement also shows the progress of the achievement completed. This is shown via a progression bar and a percentage for the achievement. Finally, each achievement is also categorized by their status: not started, in progress, or completed. This status is also displayed per achievement. If an achievement is flagged as a spoiler, it will be shown as a hidden achievement on the page. This is to avoid the achievement spoiling the story for users who have not played the game or have not progressed far enough to encounter the achievement.

To enhance user experience, the interface also features a tab system that allows users to switch between viewing all games and their pinned achievements. A recent achievements section displays the latest achievements earned by the user. Each achievement shown in the recents window shows the title alongside how recently earned the achievement was (i.e., "2 weeks ago" rather than the actual date). Interactive components such as a live search box enable real-time filtering of games and achievements, while pin buttons let users bookmark their favorite achievements. Expandable descriptions provide readability for longer texts, and animated progress bars give users a visual sense of their achievement completion.

Backend Design

The backend handles user data and achievement tracking through Django views.

Models

As part of our contributions to ChiGame, we implemented two primary models to support the achievement system: Achievement and UserAchievement. These models enable the tracking, customization, and display of player progress across different games.

Achievement Model:
Represents an individual achievement that can be earned within a game. Each achievement is associated with a specific game and contains fields such as a name, description, rarity level (e.g., Common, Rare), spoiler flag, and an optional progress threshold. The spoiler flag is a boolean that marks if the achievement would reveal story elements of the game it is associated with. The rarity of the achievement is defined by integers, with 1 being the most common and 4 being the most rare (common to precious). The progress threshold is meant for achievements that may need a certain criteria to be unlocked, rather than unlocking in a binary fashion based on circumstances ("obtain 7 coins", compared to "beat the boss").

class Achievement(models.Model):
    class Rarity(models.IntegerChoices):
        COMMON = 1, ‘Common’
        UNCOMMON = 2, ‘Uncommon’
        RARE = 3, ‘Rare’
        PRECIOUS = 4, ‘Precious’
    name = models.TextField()
    description = models.TextField(null=True, blank=True)
    spoiler = models.BooleanField()
    rarity = models.IntegerField(choices=Rarity.choices)
    game = models.ForeignKey(Game, on_delete = models.CASCADE)
    threshold = models.FloatField(null=True, blank=True, default=1)

UserAchievement Model:
Tracks a specific user's progress on a given achievement. This includes whether the achievement is pinned, the date it was earned, the last time it was updated, and current progress. It establishes a many-to-one relationship between users and achievements.

class UserAchievement(models.Model):
    user = models.ForeignKey(User, on_delete = models.CASCADE)
   achievement = models.ForeignKey(Achievement, on_delete = models.CASCADE)
   pinned = models.BooleanField()
   date_earned = models.DateTimeField()
   last_updated = models.DateTimeField(null=True, blank=True)
   progress = models.FloatField(null=True, blank=True, default=1)
   class Meta:
      unique_together = (user, achievement)

These models rely on existing User and Game models provided by the user and game teams, respectively.

Views The primary view we added is for the user achievements page, but we also added some additional views including toggling pinned achievements and getting recent achievements as helper views. There is also a view for the demo game. The user achievements view is accessed through the primary key of the user.

User Profile and Achievement Processing The system generates complete user profile pages that showcase all achievement-related data in a visually organized format. It processes raw achievement information to produce display-ready content, including progress percentages and completion statistics for each game. The system supports viewing both a user's own profile and the profiles of other users. In addition to achievement tracking, it manages the display of user avatars, join dates, and overall user statistics of the achievement.

Pin System Management
The pin system allows users to bookmark their favorite achievements for quick access and display. It handles AJAX requests to toggle the pinned status of an achievement on or off, creating or updating the corresponding achievements database as needed. When a pin action is performed, the system returns a JSON response to dynamically update the frontend without requiring a page reload. Achievements can be pinned from either the general achievements list or the dedicated pinned achievements window.

Recent Achievement Tracking The recent achievement tracking feature is a window on the user achievements page showcasing the most recent achievements that user has obtained. This window limits the results to only show the latest unlocks which can be set manually in the backend. Each achievement is fetched in the proper order, with the achievement obtained time being displayed (i.e. “2 months ago”).

For each of these features, both backend and frontend, we wrote extensive unit and integration tests to ensure that our displays were working correctly and our logic was retrieving the right data to be displayed.

Next Steps

The following are features we envision future teams implementing:

Achievement view button to redirect to the achievements page - Currently, the achievements page is only accessible by manually typing the url for ChiGame with the "/achievements" tag. Having a button on the user profile page to redirect to this page would make the process much more streamlined.

Real push notifications - Having push notifications for updates in achievements could provide users real time analysis for their progress in achievements and when it is updated.

More robust admin interface for testing: #1571 - This task could involve changing how data validation is done in the UserAchievement model or adding some specifications to the admin interface itself to allow for better testing and feedback.

Be able to see friends' achievement pages: #1583 - This future goal goes along with friend requests, which isn’t within the scope of the achievements team’s responsibilities, but once the friending feature is implemented, then a goal is to allow users to view their friends’ achievements pages.

Disable pinning achievements for other users: #1570 - Building on the previous issue, while we want users to be able to view their friends’ achievements, some permissions logic still needs to be implemented, including making sure users cannot pin/unpin other users’ achievements

UI improvements to collapsing descriptions: #1563 - This is a smaller task that involves redesigning the frontend look of the collapse button. This button is in place to collapse/expand long achievement descriptions, but future teams can make the design of the button a little more intuitive or reflective of typical collapse buttons.

Display user profile images instead of initials - Currently, the “profile images” only show users’ initials instead of actual images. Ideally, the achievements page would display the user’s profile picture if it exists.