Context module for party management.
A party is a pre-lobby grouping mechanism. Players form a party before creating or joining a lobby together.
Usage
# Create a party (user becomes leader and first member)
{:ok, party} = GameServer.Parties.create_party(user, %{max_size: 4})
# Leader invites a friend or shared-group member by user_id
{:ok, _notification} = GameServer.Parties.invite_to_party(leader, target_user_id)
# Target accepts the invite
{:ok, party} = GameServer.Parties.accept_party_invite(target, party_id)
# Or declines
:ok = GameServer.Parties.decline_party_invite(target, party_id)
# Leave a party (if leader leaves, party is disbanded)
{:ok, _} = GameServer.Parties.leave_party(user)
# Party leader creates a lobby — all members join atomically
{:ok, lobby} = GameServer.Parties.create_lobby_with_party(user, lobby_attrs)
# Party leader joins an existing lobby — all members join atomically
{:ok, lobby} = GameServer.Parties.join_lobby_with_party(user, lobby_id, opts)PubSub Events
This module broadcasts the following events:
"party:<party_id>"topic:{:party_member_joined, party_id, user_id}{:party_member_left, party_id, user_id}{:party_disbanded, party_id}{:party_updated, party}
Note: This is an SDK stub. Calling these functions will raise an error. The actual implementation runs on the GameServer.
Summary
Functions
Accept a party invite. Joins the party and marks the invite as accepted.
Admin delete of a party. Clears all members' party_id and deletes the party.
Admin update of a party (max_size, metadata).
Broadcast a member presence event (online/offline) to a party's PubSub topic.
Cancel a previously sent party invite. Only the original sender (leader) can cancel.
Return a changeset for the given party (for edit forms).
Count all parties matching the given filters.
Count total members across all parties.
Count members in a party.
The party leader creates a new lobby, and all party members join it atomically. The party is kept intact.
Create a new party. The user becomes the leader and first member.
Decline a party invite. Marks the invite as declined.
Get a party by ID. Returns nil if not found.
Get a party by ID. Raises if not found.
Get all members of a party.
Get the party the user is currently in, or nil.
Invite a user to join the party. Only the party leader may invite.
The party leader joins an existing lobby, and all party members join it atomically. The party is kept intact.
Kick a member from the party. Only the leader can kick.
Returns true if the given user is the leader of their current party.
Leave the current party.
List all parties with optional filters and pagination.
List pending party invites for the given user.
List pending party invites sent by the given leader.
The party leader quick-joins a lobby with the entire party.
Subscribe to all party events (create/delete).
Subscribe to events for a specific party.
Unsubscribe from a party's events.
Update party settings. Only the leader can update.
Functions
@spec accept_party_invite(GameServer.Accounts.User.t(), integer()) :: {:ok, GameServer.Parties.Party.t()} | {:error, atom()}
Accept a party invite. Joins the party and marks the invite as accepted.
If the user is already in another party, they automatically leave it first (disbanding if they are the leader).
Returns {:error, :no_invite} if no pending invite exists for that party.
@spec admin_delete_party(integer()) :: {:ok, GameServer.Parties.Party.t()} | {:error, term()}
Admin delete of a party. Clears all members' party_id and deletes the party.
@spec admin_update_party(GameServer.Parties.Party.t(), map()) :: {:ok, GameServer.Parties.Party.t()} | {:error, Ecto.Changeset.t()}
Admin update of a party (max_size, metadata).
Broadcast a member presence event (online/offline) to a party's PubSub topic.
@spec cancel_party_invite(GameServer.Accounts.User.t(), integer()) :: :ok | {:error, atom()}
Cancel a previously sent party invite. Only the original sender (leader) can cancel.
@spec change_party(GameServer.Parties.Party.t()) :: Ecto.Changeset.t()
Return a changeset for the given party (for edit forms).
@spec count_all_parties(map()) :: non_neg_integer()
Count all parties matching the given filters.
@spec count_all_party_members() :: non_neg_integer()
Count total members across all parties.
@spec count_party_members(integer()) :: non_neg_integer()
Count members in a party.
@spec create_lobby_with_party(GameServer.Accounts.User.t(), map()) :: {:ok, map()} | {:error, term()}
The party leader creates a new lobby, and all party members join it atomically. The party is kept intact.
The lobby's max_users must be >= party member count.
@spec create_party(GameServer.Accounts.User.t(), map()) :: {:ok, GameServer.Parties.Party.t()} | {:error, term()}
Create a new party. The user becomes the leader and first member.
Returns {:error, :already_in_party} if the user is already in a party.
@spec decline_party_invite(GameServer.Accounts.User.t(), integer()) :: :ok | {:error, atom()}
Decline a party invite. Marks the invite as declined.
@spec get_party(integer()) :: GameServer.Parties.Party.t() | nil
Get a party by ID. Returns nil if not found.
@spec get_party!(integer()) :: GameServer.Parties.Party.t()
Get a party by ID. Raises if not found.
@spec get_party_members(GameServer.Parties.Party.t() | integer()) :: [ GameServer.Accounts.User.t() ]
Get all members of a party.
@spec get_user_party(GameServer.Accounts.User.t()) :: GameServer.Parties.Party.t() | nil
Get the party the user is currently in, or nil.
@spec invite_to_party(GameServer.Accounts.User.t(), integer()) :: {:ok, GameServer.Parties.PartyInvite.t()} | {:error, atom()}
Invite a user to join the party. Only the party leader may invite.
The target user must be a friend of the leader, or share at least one group
with the leader. A PartyInvite record is created and an informational
notification is sent. The invite is independent of the notification —
deleting notifications does not affect pending invites.
Returns {:error, :not_in_party} if the caller is not in a party.
Returns {:error, :not_leader} if the caller is not the party leader.
Returns {:error, :not_connected} if the target is not a friend or shared group member.
If a pending invite already exists, returns {:ok, existing_invite} (no-op).
@spec join_lobby_with_party(GameServer.Accounts.User.t(), integer(), map()) :: {:ok, map()} | {:error, term()}
The party leader joins an existing lobby, and all party members join it atomically. The party is kept intact.
The lobby must have enough free slots for the entire party.
@spec kick_member(GameServer.Accounts.User.t(), integer()) :: {:ok, GameServer.Accounts.User.t()} | {:error, term()}
Kick a member from the party. Only the leader can kick.
@spec leader?(GameServer.Accounts.User.t()) :: boolean()
Returns true if the given user is the leader of their current party.
@spec leave_party(GameServer.Accounts.User.t()) :: {:ok, :left | :disbanded} | {:error, term()}
Leave the current party.
If the user is the party leader, the party is disbanded (all members removed, party deleted). Regular members are simply removed.
@spec list_all_parties( map(), keyword() ) :: [GameServer.Parties.Party.t()]
List all parties with optional filters and pagination.
@spec list_party_invitations(GameServer.Accounts.User.t()) :: [map()]
List pending party invites for the given user.
@spec list_sent_party_invitations(GameServer.Accounts.User.t()) :: [map()]
List pending party invites sent by the given leader.
Returns invitations the leader has sent that have not yet been accepted or declined.
@spec quick_join_with_party(GameServer.Accounts.User.t(), map()) :: {:ok, Lobby.t()} | {:error, term()}
The party leader quick-joins a lobby with the entire party.
Searches for an open lobby that matches the given criteria (title, max_users, metadata) and has enough space for the whole party. If no matching lobby is found, creates a new one and joins all party members atomically.
Returns {:ok, lobby} on success.
@spec subscribe_parties() :: :ok | {:error, term()}
Subscribe to all party events (create/delete).
Subscribe to events for a specific party.
@spec unsubscribe_party(integer()) :: :ok
Unsubscribe from a party's events.
@spec update_party(GameServer.Accounts.User.t(), map()) :: {:ok, GameServer.Parties.Party.t()} | {:error, term()}
Update party settings. Only the leader can update.