Packages
game_server_sdk
1.0.1050
1.0.1082
1.0.1079
1.0.1078
1.0.1077
1.0.1076
1.0.1075
1.0.1074
1.0.1073
1.0.1070
1.0.1068
1.0.1067
1.0.1063
1.0.1059
1.0.1058
1.0.1057
1.0.1056
1.0.1055
1.0.1050
1.0.1049
1.0.1048
1.0.1047
1.0.1046
1.0.1044
1.0.1043
1.0.1042
1.0.1041
1.0.1040
1.0.1039
1.0.1038
1.0.1034
1.0.1033
1.0.1029
1.0.1028
1.0.1026
1.0.1025
1.0.1024
1.0.1023
1.0.1022
1.0.1021
1.0.1020
1.0.1019
1.0.1018
1.0.1017
1.0.1016
1.0.1015
1.0.1014
1.0.1013
1.0.1012
1.0.1011
1.0.1009
1.0.1008
1.0.1007
1.0.1006
1.0.1005
1.0.1004
1.0.1003
1.0.1001
1.0.999
1.0.998
1.0.997
1.0.996
1.0.995
1.0.994
1.0.993
1.0.992
1.0.991
1.0.990
1.0.989
1.0.988
1.0.987
1.0.986
1.0.985
1.0.984
1.0.983
1.0.982
1.0.981
1.0.980
1.0.979
1.0.978
1.0.977
1.0.976
1.0.975
1.0.974
1.0.973
1.0.972
1.0.971
1.0.970
1.0.969
1.0.968
1.0.967
1.0.966
1.0.965
1.0.964
1.0.963
1.0.962
1.0.961
1.0.959
1.0.958
1.0.956
1.0.951
1.0.950
1.0.943
1.0.942
1.0.941
1.0.940
1.0.938
1.0.936
1.0.935
1.0.931
1.0.929
1.0.928
1.0.927
1.0.926
1.0.925
1.0.924
1.0.923
1.0.921
1.0.920
1.0.919
1.0.918
1.0.917
1.0.916
1.0.911
1.0.910
1.0.902
1.0.899
1.0.898
1.0.897
1.0.896
1.0.894
1.0.893
1.0.891
1.0.890
1.0.889
1.0.888
1.0.887
1.0.886
1.0.885
1.0.884
1.0.883
1.0.882
1.0.881
1.0.880
1.0.879
1.0.878
1.0.877
1.0.26
1.0.25
1.0.22
1.0.21
1.0.20
1.0.19
1.0.15
1.0.14
1.0.13
1.0.12
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.1.0
SDK for GameServer hooks development. Provides type specs, documentation, and IDE autocomplete for GameServer modules without requiring the full server.
Current section
Files
Jump to
Current section
Files
lib/game_server/leaderboards.ex
defmodule GameServer.Leaderboards do
@moduledoc ~S"""
The Leaderboards context.
Provides server-authoritative leaderboard management. Scores can only be
submitted via server-side code — there is no public API for score submission.
## Usage
# Create a leaderboard
{:ok, lb} = Leaderboards.create_leaderboard(%{
slug: "weekly_kills",
title: "Weekly Kills",
sort_order: :desc,
operator: :incr
})
# Submit score (server-only): resolve the active leaderboard first and submit by ID
leaderboard = Leaderboards.get_active_leaderboard_by_slug("weekly_kills")
{:ok, record} = Leaderboards.submit_score(leaderboard.id, user_id, 10)
# List records with rank (use leaderboard id)
records = Leaderboards.list_records(leaderboard.id, page: 1, limit: 25)
# Get user's record (use leaderboard id)
{:ok, record} = Leaderboards.get_user_record(leaderboard.id, user_id)
**Note:** This is an SDK stub. Calling these functions will raise an error.
The actual implementation runs on the GameServer.
"""
@doc ~S"""
Returns a changeset for a leaderboard (used in forms).
"""
@spec change_leaderboard(GameServer.Leaderboards.Leaderboard.t()) :: Ecto.Changeset.t()
def change_leaderboard(_leaderboard) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Leaderboards.change_leaderboard/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns a changeset for a leaderboard (used in forms).
"""
@spec change_leaderboard(GameServer.Leaderboards.Leaderboard.t(), map()) :: Ecto.Changeset.t()
def change_leaderboard(_leaderboard, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Leaderboards.change_leaderboard/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns a changeset for a record (used in admin forms).
"""
@spec change_record(GameServer.Leaderboards.Record.t()) :: Ecto.Changeset.t()
def change_record(_record) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Leaderboards.change_record/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Returns a changeset for a record (used in admin forms).
"""
@spec change_record(GameServer.Leaderboards.Record.t(), map()) :: Ecto.Changeset.t()
def change_record(_record, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Leaderboards.change_record/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Count all leaderboard records across all leaderboards.
"""
@spec count_all_records() :: non_neg_integer()
def count_all_records() do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Leaderboards.count_all_records/0 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Counts unique leaderboard slugs.
"""
@spec count_leaderboard_groups() :: non_neg_integer()
def count_leaderboard_groups() do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Leaderboards.count_leaderboard_groups/0 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Counts leaderboards matching the given filters.
Accepts the same filter options as `list_leaderboards/1`.
"""
@spec count_leaderboards() :: non_neg_integer()
def count_leaderboards() do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Leaderboards.count_leaderboards/0 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Counts leaderboards matching the given filters.
Accepts the same filter options as `list_leaderboards/1`.
"""
@spec count_leaderboards(keyword()) :: non_neg_integer()
def count_leaderboards(_opts) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Leaderboards.count_leaderboards/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Counts records for a leaderboard.
"""
@spec count_records(Ecto.UUID.t()) :: non_neg_integer()
def count_records(_leaderboard_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Leaderboards.count_records/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Counts records for a leaderboard.
"""
@spec count_records(
Ecto.UUID.t(),
keyword()
) :: non_neg_integer()
def count_records(_leaderboard_id, _opts) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Leaderboards.count_records/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Creates a new leaderboard.
## Attributes
See `t:GameServer.Types.leaderboard_create_attrs/0` for available fields.
## Examples
iex> create_leaderboard(%{slug: "my_lb", title: "My Leaderboard"})
{:ok, %Leaderboard{}}
iex> create_leaderboard(%{slug: "", title: ""})
{:error, %Ecto.Changeset{}}
"""
@spec create_leaderboard(GameServer.Types.leaderboard_create_attrs()) ::
{:ok, GameServer.Leaderboards.Leaderboard.t()} | {:error, Ecto.Changeset.t()}
def create_leaderboard(_attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Leaderboards.Leaderboard{id: 0, slug: "", title: "", description: nil, sort_order: :desc, operator: :set, starts_at: nil, ends_at: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Leaderboards.create_leaderboard/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Deletes a leaderboard and all its records.
"""
@spec delete_leaderboard(GameServer.Leaderboards.Leaderboard.t()) ::
{:ok, GameServer.Leaderboards.Leaderboard.t()} | {:error, Ecto.Changeset.t()}
def delete_leaderboard(_leaderboard) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Leaderboards.Leaderboard{id: 0, slug: "", title: "", description: nil, sort_order: :desc, operator: :set, starts_at: nil, ends_at: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Leaderboards.delete_leaderboard/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Deletes a record.
"""
@spec delete_record(GameServer.Leaderboards.Record.t()) ::
{:ok, GameServer.Leaderboards.Record.t()} | {:error, Ecto.Changeset.t()}
def delete_record(_record) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Leaderboards.delete_record/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Deletes a user's record from a leaderboard.
Accepts either leaderboard ID or slug (both strings).
"""
@spec delete_user_record(String.t(), Ecto.UUID.t()) ::
{:ok, GameServer.Leaderboards.Record.t()} | {:error, :not_found}
def delete_user_record(_id_or_slug, _user_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Leaderboards.delete_user_record/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Ends a leaderboard by setting `ends_at` to the current time.
"""
@spec end_leaderboard(GameServer.Leaderboards.Leaderboard.t() | String.t()) ::
{:ok, GameServer.Leaderboards.Leaderboard.t()} | {:error, Ecto.Changeset.t() | :not_found}
def end_leaderboard(_leaderboard) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Leaderboards.Leaderboard{id: 0, slug: "", title: "", description: nil, sort_order: :desc, operator: :set, starts_at: nil, ends_at: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Leaderboards.end_leaderboard/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets the currently active leaderboard with the given slug.
Returns `nil` if no active leaderboard exists.
An active leaderboard is one that:
- Has not ended (`ends_at` is nil or in the future)
- Has started (`starts_at` is nil or in the past)
If multiple active leaderboards exist with the same slug,
returns the most recently created one.
"""
@spec get_active_leaderboard_by_slug(String.t()) :: GameServer.Leaderboards.Leaderboard.t() | nil
def get_active_leaderboard_by_slug(_slug) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Leaderboards.Leaderboard{id: 0, slug: "", title: "", description: nil, sort_order: :desc, operator: :set, starts_at: nil, ends_at: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Leaderboards.get_active_leaderboard_by_slug/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets a single record by leaderboard ID and label.
"""
@spec get_label_record(Ecto.UUID.t(), String.t()) :: GameServer.Leaderboards.Record.t() | nil
def get_label_record(_leaderboard_id, _label) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Leaderboards.get_label_record/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets a leaderboard by its UUID, or the active leaderboard by slug.
## Examples
iex> get_leaderboard("0198c0de-...")
%Leaderboard{}
iex> get_leaderboard(Ecto.UUID.generate())
nil
"""
@spec get_leaderboard(String.t()) :: GameServer.Leaderboards.Leaderboard.t() | nil
def get_leaderboard(_id_or_slug) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Leaderboards.Leaderboard{id: 0, slug: "", title: "", description: nil, sort_order: :desc, operator: :set, starts_at: nil, ends_at: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Leaderboards.get_leaderboard/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets a leaderboard by its ID. Raises if not found.
"""
@spec get_leaderboard!(String.t()) :: GameServer.Leaderboards.Leaderboard.t()
def get_leaderboard!(_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Leaderboards.get_leaderboard!/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets a single record by leaderboard ID and user ID.
"""
@spec get_record(Ecto.UUID.t(), Ecto.UUID.t()) :: GameServer.Leaderboards.Record.t() | nil
def get_record(_leaderboard_id, _user_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
if :erlang.phash2(make_ref(), 2) == 0, do: nil, else: %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}
_ ->
raise "GameServer.Leaderboards.get_record/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets a record by its ID. Raises if not found.
Intended for internal/admin usage.
"""
@spec get_record!(Ecto.UUID.t()) :: GameServer.Leaderboards.Record.t()
def get_record!(_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
nil
_ ->
raise "GameServer.Leaderboards.get_record!/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Gets a user's record with their rank.
Returns `{:ok, record_with_rank}` or `{:error, :not_found}`.
"""
@spec get_user_record(Ecto.UUID.t(), Ecto.UUID.t()) ::
{:ok, GameServer.Leaderboards.Record.t()} | {:error, :not_found}
def get_user_record(_leaderboard_id, _user_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Leaderboards.get_user_record/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Lists unique leaderboard slugs with summary info.
Returns a list of maps with:
- `:slug` - the leaderboard slug
- `:title` - title from the latest leaderboard
- `:description` - description from the latest leaderboard
- `:active_id` - ID of the currently active leaderboard (or nil)
- `:latest_id` - ID of the most recent leaderboard
- `:season_count` - total number of leaderboards with this slug
"""
@spec list_leaderboard_groups() :: [map()]
def list_leaderboard_groups() do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
%{}
_ ->
raise "GameServer.Leaderboards.list_leaderboard_groups/0 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Lists unique leaderboard slugs with summary info.
Returns a list of maps with:
- `:slug` - the leaderboard slug
- `:title` - title from the latest leaderboard
- `:description` - description from the latest leaderboard
- `:active_id` - ID of the currently active leaderboard (or nil)
- `:latest_id` - ID of the most recent leaderboard
- `:season_count` - total number of leaderboards with this slug
"""
@spec list_leaderboard_groups(keyword()) :: [map()]
def list_leaderboard_groups(_opts) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
%{}
_ ->
raise "GameServer.Leaderboards.list_leaderboard_groups/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Lists leaderboards with optional filters.
## Options
* `:slug` - Filter by slug (returns all seasons of that leaderboard)
* `:active` - If `true`, only active leaderboards. If `false`, only ended.
* `:order_by` - Order by field: `:ends_at` or `:inserted_at` (default)
* `:starts_after` - Only leaderboards that started after this DateTime
* `:starts_before` - Only leaderboards that started before this DateTime
* `:ends_after` - Only leaderboards that end after this DateTime
* `:ends_before` - Only leaderboards that end before this DateTime
* `:page` - Page number (default 1)
* `:page_size` - Page size (default 25)
## Examples
iex> list_leaderboards(active: true)
[%Leaderboard{}, ...]
iex> list_leaderboards(slug: "weekly_kills")
[%Leaderboard{}, ...]
iex> list_leaderboards(starts_after: ~U[2025-01-01 00:00:00Z])
[%Leaderboard{}, ...]
"""
@spec list_leaderboards() :: [GameServer.Leaderboards.Leaderboard.t()]
def list_leaderboards() do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
[]
_ ->
raise "GameServer.Leaderboards.list_leaderboards/0 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Lists leaderboards with optional filters.
## Options
* `:slug` - Filter by slug (returns all seasons of that leaderboard)
* `:active` - If `true`, only active leaderboards. If `false`, only ended.
* `:order_by` - Order by field: `:ends_at` or `:inserted_at` (default)
* `:starts_after` - Only leaderboards that started after this DateTime
* `:starts_before` - Only leaderboards that started before this DateTime
* `:ends_after` - Only leaderboards that end after this DateTime
* `:ends_before` - Only leaderboards that end before this DateTime
* `:page` - Page number (default 1)
* `:page_size` - Page size (default 25)
## Examples
iex> list_leaderboards(active: true)
[%Leaderboard{}, ...]
iex> list_leaderboards(slug: "weekly_kills")
[%Leaderboard{}, ...]
iex> list_leaderboards(starts_after: ~U[2025-01-01 00:00:00Z])
[%Leaderboard{}, ...]
"""
@spec list_leaderboards(keyword()) :: [GameServer.Leaderboards.Leaderboard.t()]
def list_leaderboards(_opts) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
[]
_ ->
raise "GameServer.Leaderboards.list_leaderboards/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Lists all leaderboards with the given slug (all seasons), ordered by end date.
"""
@spec list_leaderboards_by_slug(String.t()) :: [GameServer.Leaderboards.Leaderboard.t()]
def list_leaderboards_by_slug(_slug) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
[]
_ ->
raise "GameServer.Leaderboards.list_leaderboards_by_slug/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Lists all leaderboards with the given slug (all seasons), ordered by end date.
"""
@spec list_leaderboards_by_slug(
String.t(),
keyword()
) :: [GameServer.Leaderboards.Leaderboard.t()]
def list_leaderboards_by_slug(_slug, _opts) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
[]
_ ->
raise "GameServer.Leaderboards.list_leaderboards_by_slug/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Lists records for a leaderboard, ordered by rank.
## Options
See `t:GameServer.Types.pagination_opts/0` for available options.
Returns records with `rank` field populated.
"""
@spec list_records(String.t()) :: [GameServer.Leaderboards.Record.t()]
def list_records(_leaderboard_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
[]
_ ->
raise "GameServer.Leaderboards.list_records/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Lists records for a leaderboard, ordered by rank.
## Options
See `t:GameServer.Types.pagination_opts/0` for available options.
Returns records with `rank` field populated.
"""
@spec list_records(String.t(), GameServer.Types.pagination_opts()) :: [
GameServer.Leaderboards.Record.t()
]
def list_records(_leaderboard_id, _opts) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
[]
_ ->
raise "GameServer.Leaderboards.list_records/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Lists records around a specific user (centered on their position).
Returns records above and below the user's rank.
## Options
* `:limit` - Total number of records to return (default 11, centered on user)
"""
@spec list_records_around_user(String.t(), Ecto.UUID.t()) :: [GameServer.Leaderboards.Record.t()]
def list_records_around_user(_leaderboard_id, _user_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
[]
_ ->
raise "GameServer.Leaderboards.list_records_around_user/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Lists records around a specific user (centered on their position).
Returns records above and below the user's rank.
## Options
* `:limit` - Total number of records to return (default 11, centered on user)
"""
@spec list_records_around_user(String.t(), Ecto.UUID.t(), keyword()) :: [
GameServer.Leaderboards.Record.t()
]
def list_records_around_user(_leaderboard_id, _user_id, _opts) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
[]
_ ->
raise "GameServer.Leaderboards.list_records_around_user/3 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Resolves multiple slugs to their currently active leaderboards in a single query.
Returns a map of `slug => %Leaderboard{}` for each slug that has an active
leaderboard. Slugs with no active leaderboard are omitted from the result.
## Examples
iex> resolve_slugs(["weekly_kills", "monthly_score", "nonexistent"])
%{
"weekly_kills" => %Leaderboard{id: 1, slug: "weekly_kills", ...},
"monthly_score" => %Leaderboard{id: 5, slug: "monthly_score", ...}
}
"""
@spec resolve_slugs([String.t()]) :: %{required(String.t()) => GameServer.Leaderboards.Leaderboard.t()}
def resolve_slugs(_slugs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
""
_ ->
raise "GameServer.Leaderboards.resolve_slugs/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Submit a score for a label-based (non-user) record.
Works just like `submit_score/4` but uses a string label instead of a user ID.
This is useful for statistics, rankings by category, etc.
## Examples
iex> submit_label_score(leaderboard_id, "English", 42)
{:ok, %Record{label: "English", score: 42}}
"""
@spec submit_label_score(String.t(), String.t(), integer(), map()) ::
{:ok, GameServer.Leaderboards.Record.t()} | {:error, term()}
def submit_label_score(_leaderboard_id, _label, _score, _metadata) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Leaderboards.submit_label_score/4 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Submits a score for a user on a leaderboard.
This is a server-only function — there is no public API for score submission.
The score is processed according to the leaderboard's operator:
* `:set` — Always replace with new score
* `:best` — Only update if new score is better (respects sort_order)
* `:incr` — Add to existing score
* `:decr` — Subtract from existing score
To submit to a leaderboard by slug, first get the active leaderboard ID:
leaderboard = Leaderboards.get_active_leaderboard_by_slug("weekly_kills")
Leaderboards.submit_score(leaderboard.id, user_id, 10)
## Examples
iex> submit_score(123, user_id, 10)
{:ok, %Record{score: 10}}
iex> submit_score(123, user_id, 5, %{weapon: "sword"})
{:ok, %Record{score: 15, metadata: %{weapon: "sword"}}}
"""
@spec submit_score(String.t(), Ecto.UUID.t(), integer()) ::
{:ok, GameServer.Leaderboards.Record.t()} | {:error, term()}
def submit_score(_leaderboard_id, _user_id, _score) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Leaderboards.submit_score/3 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Submits a score for a user on a leaderboard.
This is a server-only function — there is no public API for score submission.
The score is processed according to the leaderboard's operator:
* `:set` — Always replace with new score
* `:best` — Only update if new score is better (respects sort_order)
* `:incr` — Add to existing score
* `:decr` — Subtract from existing score
To submit to a leaderboard by slug, first get the active leaderboard ID:
leaderboard = Leaderboards.get_active_leaderboard_by_slug("weekly_kills")
Leaderboards.submit_score(leaderboard.id, user_id, 10)
## Examples
iex> submit_score(123, user_id, 10)
{:ok, %Record{score: 10}}
iex> submit_score(123, user_id, 5, %{weapon: "sword"})
{:ok, %Record{score: 15, metadata: %{weapon: "sword"}}}
"""
@spec submit_score(String.t(), Ecto.UUID.t(), integer(), map()) ::
{:ok, GameServer.Leaderboards.Record.t()} | {:error, term()}
def submit_score(_leaderboard_id, _user_id, _score, _metadata) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Leaderboards.submit_score/4 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Updates an existing leaderboard.
Note: `slug`, `sort_order`, and `operator` cannot be changed after creation.
## Attributes
See `t:GameServer.Types.leaderboard_update_attrs/0` for available fields.
"""
@spec update_leaderboard(
GameServer.Leaderboards.Leaderboard.t(),
GameServer.Types.leaderboard_update_attrs()
) :: {:ok, GameServer.Leaderboards.Leaderboard.t()} | {:error, Ecto.Changeset.t()}
def update_leaderboard(_leaderboard, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Leaderboards.Leaderboard{id: 0, slug: "", title: "", description: nil, sort_order: :desc, operator: :set, starts_at: nil, ends_at: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Leaderboards.update_leaderboard/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Updates an existing record.
Intended for internal/admin usage.
"""
@spec update_record(GameServer.Leaderboards.Record.t(), map()) ::
{:ok, GameServer.Leaderboards.Record.t()} | {:error, Ecto.Changeset.t()}
def update_record(_record, _attrs) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, %GameServer.Leaderboards.Record{id: 0, leaderboard_id: 0, user_id: 0, label: nil, score: 0, rank: nil, metadata: %{}, inserted_at: ~U[1970-01-01 00:00:00Z], updated_at: ~U[1970-01-01 00:00:00Z]}}
_ ->
raise "GameServer.Leaderboards.update_record/2 is a stub - only available at runtime on GameServer"
end
end
end