Skip to main content
The useMatchLobbyStore is a Pinia store that manages match lobbies, tournaments, and real-time participant tracking for the 5Stack platform.

Overview

This store handles:
  • User’s active and scheduled matches
  • Match and tournament counts for organizers
  • Live match and tournament tracking
  • Lobby chat participant management
  • Real-time subscriptions for various match states

Import

import { useMatchLobbyStore } from '~/stores/MatchLobbyStore';

Usage

const matchLobbyStore = useMatchLobbyStore();

// Get current match
const currentMatch = matchLobbyStore.currentMatch;

// Check organizer counts
if (matchLobbyStore.managingMatchesCount > 0) {
  console.log('You have matches to manage');
}

// Add user to lobby chat
matchLobbyStore.add(matchId, {
  steam_id: '76561198012345678',
  name: 'Player Name',
  avatar_url: 'https://...',
  inGame: false,
});

State

Match Management

myMatches
Ref<Array>
All matches the user is involved in (as player or organizer) that are active or scheduled.
lobbyChat
Ref<Record<string, Map<string, unknown>>>
Map of match IDs to participant data for lobby chat, tracking who’s in each lobby.

Counts

managingMatchesCount
Ref<number>
Number of active matches the user is organizing (for match organizers and above).
managingTournamentsCount
Ref<number>
Number of active tournaments the user is organizing (for tournament organizers and above).
liveMatchesCount
Ref<number>
Total number of live matches across the platform.
liveTournamentsCount
Ref<number>
Total number of live tournaments across the platform.
openRegistrationTournamentsCount
Ref<number>
Number of tournaments currently open for registration.
openMatchesCount
Ref<number>
Number of matches in player selection that are open to join.

Tournaments

chatTournaments
Ref<Array>
Live tournaments where the user is either a participant or organizer (for chat access).

Methods

Subscription Methods

subscribeToMyMatches()

Subscribes to matches the user is involved in as a player or organizer.
async subscribeToMyMatches(): Promise<void>
Example:
await matchLobbyStore.subscribeToMyMatches();

subscribeToLiveMatches()

Subscribes to the count of all live matches on the platform.
async subscribeToLiveMatches(): Promise<void>

subscribeToLiveTournaments()

Subscribes to the count of all live tournaments on the platform.
async subscribeToLiveTournaments(): Promise<void>

subscribeToOpenRegistrationTournaments()

Subscribes to the count of tournaments open for registration.
async subscribeToOpenRegistrationTournaments(): Promise<void>

subscribeToOpenMatches()

Subscribes to the count of matches open for players to join.
async subscribeToOpenMatches(): Promise<void>

subscribeToChatTournaments()

Subscribes to tournaments where the user has chat access (as participant or organizer).
async subscribeToChatTournaments(): Promise<void>

subscribeToManagingMatches()

Subscribes to active matches the user is organizing. Only available for match organizers and above.
async subscribeToManagingMatches(): Promise<void>
Example:
if (authStore.isRoleAbove(e_player_roles_enum.match_organizer)) {
  await matchLobbyStore.subscribeToManagingMatches();
}

subscribeToManagingTournaments()

Subscribes to active tournaments the user is organizing. Only available for tournament organizers and above.
async subscribeToManagingTournaments(): Promise<void>
Example:
if (authStore.isRoleAbove(e_player_roles_enum.tournament_organizer)) {
  await matchLobbyStore.subscribeToManagingTournaments();
}

Lobby Chat Management

add()

Adds a user to a match lobby’s participant list.
add(
  matchId: string,
  user: {
    name: string;
    steam_id: string;
    avatar_url: string;
    inGame: boolean;
  }
): void
matchId
string
required
The ID of the match lobby
user
Object
required
User object containing:
  • steam_id: User’s Steam ID
  • name: Display name
  • avatar_url: Profile picture URL
  • inGame: Whether user is currently in-game
Example:
matchLobbyStore.add('match-123', {
  steam_id: '76561198012345678',
  name: 'PlayerOne',
  avatar_url: 'https://avatars.steamstatic.com/...',
  inGame: true,
});

set()

Sets multiple users as participants in a match lobby.
set(
  matchId: string,
  users: Array<{
    steam_id: string;
    name: string;
    avatar_url: string;
  }>
): void
matchId
string
required
The ID of the match lobby
users
Array
required
Array of user objects
Example:
matchLobbyStore.set('match-123', [
  {
    steam_id: '76561198012345678',
    name: 'PlayerOne',
    avatar_url: 'https://...',
  },
  {
    steam_id: '76561198087654321',
    name: 'PlayerTwo',
    avatar_url: 'https://...',
  },
]);

remove()

Removes a user from a match lobby’s participant list.
remove(
  matchId: string,
  user: { steam_id: string }
): void
matchId
string
required
The ID of the match lobby
user
Object
required
Object containing the user’s steam_id
Example:
matchLobbyStore.remove('match-123', {
  steam_id: '76561198012345678',
});

Computed Properties

currentMatch
ComputedRef<Object | undefined>
The first match in myMatches array (most recent/active match).

Match Status Types

The store tracks matches with the following statuses:
  • Live - Match is currently being played
  • Veto - Map veto phase in progress
  • WaitingForCheckIn - Waiting for players to check in
  • WaitingForServer - Server is being provisioned
  • Scheduled - Match is scheduled for future
  • PickingPlayers - Players are being selected for the match

Tournament Status Types

The store tracks tournaments with the following statuses:
  • Live - Tournament is in progress
  • RegistrationOpen - Registration is open
  • RegistrationClosed - Registration closed, waiting to start
  • Setup - Tournament is being configured

Example: Organizer Dashboard

const matchLobbyStore = useMatchLobbyStore();
const authStore = useAuthStore();

const organizerStats = computed(() => {
  const stats = [];

  if (authStore.isRoleAbove(e_player_roles_enum.match_organizer)) {
    stats.push({
      label: 'Managing Matches',
      count: matchLobbyStore.managingMatchesCount,
      link: '/manage/matches',
    });
  }

  if (authStore.isRoleAbove(e_player_roles_enum.tournament_organizer)) {
    stats.push({
      label: 'Managing Tournaments',
      count: matchLobbyStore.managingTournamentsCount,
      link: '/manage/tournaments',
    });
  }

  return stats;
});

Example: Live Activity Widget

const matchLobbyStore = useMatchLobbyStore();

const platformActivity = computed(() => ({
  liveMatches: matchLobbyStore.liveMatchesCount,
  liveTournaments: matchLobbyStore.liveTournamentsCount,
  openMatches: matchLobbyStore.openMatchesCount,
  openTournaments: matchLobbyStore.openRegistrationTournamentsCount,
}));

Example: Lobby Participants Display

const matchLobbyStore = useMatchLobbyStore();
const matchId = 'match-123';

const lobbyParticipants = computed(() => {
  const participants = matchLobbyStore.lobbyChat[matchId];
  if (!participants) return [];
  
  return Array.from(participants.values()).map(user => ({
    steamId: user.steam_id,
    name: user.name,
    avatar: user.avatar_url,
    inGame: user.inGame,
  }));
});

Build docs developers (and LLMs) love