Packages
game_server_sdk
1.0.1063
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/economy.ex
defmodule GameServer.Economy do
@moduledoc ~S"""
Virtual-currency wallets with an append-only ledger.
Currencies are free-form string codes (`"gold"`, `"gems"`, `"energy"`) — the
game decides which exist. Every balance change is atomic and recorded in the
ledger, so two concurrent spends can never overspend and every mutation is
auditable.
## Usage (server-side / hooks)
Economy.grant(user_id, "gold", 100, reason: "match_reward")
case Economy.spend(user_id, "gold", 30, reason: "store_purchase") do
{:ok, balance} -> :ok
{:error, :insufficient_funds} -> :not_enough_gold
end
Economy.balance(user_id, "gold") #=> 70
Economy.balances(user_id) #=> %{"gold" => 70}
## Idempotency
Pass `:idempotency_key` so a retried request (network retry, at-least-once job)
can't double-apply — the second call is a no-op that returns the current
balance:
Economy.grant(user_id, "gems", 5, idempotency_key: "purchase:#{order_id}")
## Safety
These are **server-authoritative**: expose them from hooks and admin tools,
never as a raw client "add currency" endpoint. Clients only read their wallet.
**Note:** This is an SDK stub. Calling these functions will raise an error.
The actual implementation runs on the GameServer.
"""
@type currency() :: String.t()
@type user_id() :: Ecto.UUID.t()
@doc ~S"""
Current balance of one currency (0 when the user has no wallet for it).
"""
@spec balance(user_id(), currency()) :: non_neg_integer()
def balance(_user_id, _currency) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Economy.balance/2 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
All non-zero balances for a user, as a `%{currency => balance}` map.
"""
@spec balances(user_id()) :: %{required(currency()) => non_neg_integer()}
def balances(_user_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
0
_ ->
raise "GameServer.Economy.balances/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Add `amount` of `currency` to a user's wallet.
Options: `:reason` (ledger label), `:idempotency_key`, `:metadata`.
Returns `{:ok, new_balance}`.
"""
@spec grant(user_id(), currency(), pos_integer(), keyword()) ::
{:ok, non_neg_integer()} | {:error, term()}
def grant(_user_id, _currency, _amount, _opts) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, nil}
_ ->
raise "GameServer.Economy.grant/4 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Remove `amount` of `currency` from a user's wallet, atomically.
Returns `{:ok, new_balance}` or `{:error, :insufficient_funds}` — the balance
is never left negative.
"""
@spec spend(user_id(), currency(), pos_integer(), keyword()) ::
{:ok, non_neg_integer()} | {:error, :insufficient_funds | term()}
def spend(_user_id, _currency, _amount, _opts) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
{:ok, nil}
_ ->
raise "GameServer.Economy.spend/4 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Subscribe the calling process to a user's live wallet updates.
"""
@spec subscribe(user_id()) :: :ok | {:error, term()}
def subscribe(_user_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
:ok
_ ->
raise "GameServer.Economy.subscribe/1 is a stub - only available at runtime on GameServer"
end
end
@doc ~S"""
Stop receiving a user's wallet updates.
"""
@spec unsubscribe(user_id()) :: :ok
def unsubscribe(_user_id) do
case Application.get_env(:game_server_sdk, :stub_mode, :raise) do
:placeholder ->
:ok
_ ->
raise "GameServer.Economy.unsubscribe/1 is a stub - only available at runtime on GameServer"
end
end
end