GameServer.Hooks behaviour (game_server_sdk v0.1.0)
View SourceBehaviour for GameServer hooks/callbacks.
Implement this behaviour in your hooks module to receive lifecycle events from the GameServer and run custom game logic.
Setup
- Create a module implementing this behaviour
- Configure it in your GameServer instance
Example
defmodule MyGame.Hooks do
@behaviour GameServer.Hooks
@impl true
def after_user_register(user) do
# Give new users starting coins
GameServer.Accounts.update_user(user, %{
metadata: Map.put(user.metadata || %{}, "coins", 100)
})
end
@impl true
def after_user_login(user) do
# Log login
:ok
end
# Lobby hooks
@impl true
def before_lobby_create(attrs) do
# Validate or modify lobby creation attributes
{:ok, attrs}
end
@impl true
def after_lobby_create(_lobby), do: :ok
@impl true
def before_lobby_join(user, lobby, opts) do
# Check if user can join (e.g., level requirements)
{:ok, {user, lobby, opts}}
end
@impl true
def after_lobby_join(_user, _lobby), do: :ok
@impl true
def before_lobby_leave(user, lobby) do
{:ok, {user, lobby}}
end
@impl true
def after_lobby_leave(_user, _lobby), do: :ok
@impl true
def before_lobby_update(_lobby, attrs) do
{:ok, attrs}
end
@impl true
def after_lobby_update(_lobby), do: :ok
@impl true
def before_lobby_delete(lobby) do
{:ok, lobby}
end
@impl true
def after_lobby_delete(_lobby), do: :ok
@impl true
def before_user_kicked(host, target, lobby) do
{:ok, {host, target, lobby}}
end
@impl true
def after_user_kicked(_host, _target, _lobby), do: :ok
@impl true
def after_lobby_host_change(_lobby, _new_host_id), do: :ok
# Custom RPC handlers - define your own functions!
# These are called from game clients via the RPC channel.
#
# def give_coins(amount, opts) do
# caller = Keyword.get(opts, :caller)
# # Update user's coins...
# {:ok, %{new_balance: 150}}
# end
endHook Types
User Lifecycle Hooks
after_user_register/1- Called after a new user registersafter_user_login/1- Called after a user logs in
Lobby Lifecycle Hooks
Before hooks can block operations by returning {:error, reason}.
After hooks are fire-and-forget.
before_lobby_create/1- Before lobby creation, receives attrs mapafter_lobby_create/1- After lobby is createdbefore_lobby_join/3- Before user joins lobbyafter_lobby_join/2- After user joins lobbybefore_lobby_leave/2- Before user leaves lobbyafter_lobby_leave/2- After user leaves lobbybefore_lobby_update/2- Before lobby is updatedafter_lobby_update/1- After lobby is updatedbefore_lobby_delete/1- Before lobby is deletedafter_lobby_delete/1- After lobby is deletedbefore_user_kicked/3- Before user is kicked from lobbyafter_user_kicked/3- After user is kicked from lobbyafter_lobby_host_change/2- After lobby host changes
Custom RPC Functions
Any public function in your hooks module (other than the callbacks above)
can be called from game clients via the RPC channel. The function receives
its arguments plus a keyword list with :caller containing the authenticated user.
# Client calls: rpc("give_coins", {amount: 50})
def give_coins(amount, opts) do
caller = Keyword.get(opts, :caller)
# Your game logic here
{:ok, %{success: true}}
endReturn values:
{:ok, data}- Success, data is sent back to client{:error, reason}- Error, reason is sent back to client:ok- Success with no data
Summary
Types
Result type for before hooks
A lobby struct from GameServer.Lobbies.Lobby
A user struct from GameServer.Accounts.User
Functions
Use this macro to get default implementations for all callbacks.
Types
@type hook_result(t) :: {:ok, t} | {:error, term()}
Result type for before hooks
@type lobby() :: GameServer.Lobbies.Lobby.t()
A lobby struct from GameServer.Lobbies.Lobby
@type user() :: GameServer.Accounts.User.t()
A user struct from GameServer.Accounts.User
Callbacks
@callback before_lobby_create(attrs :: map()) :: hook_result(map())
@callback before_lobby_delete(lobby()) :: hook_result(lobby())
@callback before_lobby_leave(user(), lobby()) :: hook_result({user(), lobby()})
@callback before_lobby_update(lobby(), attrs :: map()) :: hook_result(map())