GameServer.Achievements
(game_server_core v1.0.940)
Copy Markdown
The Achievements context.
Manages achievement definitions and user progress/unlocks.
Usage
# Create an achievement (admin)
{:ok, ach} = Achievements.create_achievement(%{
slug: "first_lobby",
title: "Welcome!",
description: "Join your first lobby",
progress_target: 1
})
# Unlock a one-shot achievement
{:ok, ua} = Achievements.unlock_achievement(user_id, "first_lobby")
# Increment progress on a multi-step achievement
{:ok, ua} = Achievements.increment_progress(user_id, "chat_100", 1)
# auto-unlocks when progress >= progress_target
# List achievements (with user progress if user_id provided)
achievements = Achievements.list_achievements(user_id: user_id, page: 1, page_size: 25)
Summary
Functions
Returns a changeset for tracking achievement changes (used by forms).
Count achievements (for pagination). Supports :include_hidden, :filter, and :user_id.
Count all achievements (including hidden), for admin dashboard.
Count all user achievement unlock records.
Count hidden achievements.
Count unlocked achievements for a user.
Count distinct users who have unlocked at least one achievement.
Creates a new achievement definition.
Returns achievement statistics for the admin dashboard.
Deletes an achievement and all related user progress.
Get an achievement by ID.
Get an achievement by slug.
Get a user's progress on a specific achievement.
Grant achievement to user by slug (admin convenience, calls unlock_achievement).
Increment progress on an achievement for a user. Automatically unlocks when progress reaches the target.
Lists all achievements, optionally with user progress.
Lists all achievements unlocked by a user.
Reset a user's progress on a specific achievement (admin use).
Revoke an achievement from a user. Deletes the user_achievement record entirely.
Subscribe to global achievement events (new definitions, updates, unlocks).
Unlock an achievement for a user by slug. If it's a progress-based achievement, sets progress to the target and marks it as unlocked.
Get unlock percentage for an achievement (0.0 to 100.0).
Updates an achievement definition.
Functions
@spec change_achievement(GameServer.Achievements.Achievement.t(), map()) :: Ecto.Changeset.t()
Returns a changeset for tracking achievement changes (used by forms).
@spec count_achievements(keyword()) :: non_neg_integer()
Count achievements (for pagination). Supports :include_hidden, :filter, and :user_id.
@spec count_all_achievements() :: non_neg_integer()
Count all achievements (including hidden), for admin dashboard.
@spec count_all_unlocks() :: non_neg_integer()
Count all user achievement unlock records.
@spec count_user_achievements(integer()) :: non_neg_integer()
Count unlocked achievements for a user.
@spec count_users_with_unlocks() :: non_neg_integer()
Count distinct users who have unlocked at least one achievement.
@spec create_achievement(map()) :: {:ok, GameServer.Achievements.Achievement.t()} | {:error, Ecto.Changeset.t()}
Creates a new achievement definition.
@spec dashboard_stats() :: map()
Returns achievement statistics for the admin dashboard.
Returns a map with:
hidden— number of hidden achievementsusers_with_unlocks— users who unlocked at least oneavg_unlocks_per_user— average unlocks per user (among users who have any)most_unlocked—{slug, title, count}of the most-unlocked achievementleast_unlocked—{slug, title, count}of the least-unlocked achievement (with at least 1 unlock)
@spec delete_achievement(GameServer.Achievements.Achievement.t()) :: {:ok, GameServer.Achievements.Achievement.t()} | {:error, Ecto.Changeset.t()}
Deletes an achievement and all related user progress.
@spec get_achievement(integer()) :: GameServer.Achievements.Achievement.t() | nil
Get an achievement by ID.
@spec get_achievement_by_slug(String.t()) :: GameServer.Achievements.Achievement.t() | nil
Get an achievement by slug.
@spec get_user_achievement(integer(), integer()) :: GameServer.Achievements.UserAchievement.t() | nil
Get a user's progress on a specific achievement.
@spec grant_achievement(integer(), String.t()) :: {:ok, GameServer.Achievements.UserAchievement.t()} | {:error, atom()}
Grant achievement to user by slug (admin convenience, calls unlock_achievement).
@spec increment_progress(integer(), String.t(), pos_integer()) :: {:ok, GameServer.Achievements.UserAchievement.t()} | {:error, atom()}
Increment progress on an achievement for a user. Automatically unlocks when progress reaches the target.
Returns {:ok, user_achievement}.
Lists all achievements, optionally with user progress.
Options
:user_id— if provided, includes user progress/unlock status:page— page number (default: 1):page_size— items per page (default: 25):include_hidden— if true, include hidden achievements (default: false)
@spec list_user_achievements( integer(), keyword() ) :: [GameServer.Achievements.UserAchievement.t()]
Lists all achievements unlocked by a user.
@spec reset_user_achievement(integer(), integer()) :: {:ok, GameServer.Achievements.UserAchievement.t() | :not_found} | {:error, Ecto.Changeset.t()}
Reset a user's progress on a specific achievement (admin use).
@spec revoke_achievement(integer(), integer()) :: {:ok, GameServer.Achievements.UserAchievement.t()} | {:error, atom()}
Revoke an achievement from a user. Deletes the user_achievement record entirely.
@spec subscribe_achievements() :: :ok | {:error, term()}
Subscribe to global achievement events (new definitions, updates, unlocks).
@spec unlock_achievement(integer(), String.t() | integer()) :: {:ok, GameServer.Achievements.UserAchievement.t()} | {:error, atom()}
Unlock an achievement for a user by slug. If it's a progress-based achievement, sets progress to the target and marks it as unlocked.
Returns {:ok, user_achievement} or {:error, reason}.
Get unlock percentage for an achievement (0.0 to 100.0).
@spec update_achievement(GameServer.Achievements.Achievement.t(), map()) :: {:ok, GameServer.Achievements.Achievement.t()} | {:error, Ecto.Changeset.t()}
Updates an achievement definition.