Skip to main content

Tournaments Overview

Tournaments are structured competitive events that allow players to compete in time-based challenges with specific rules and scoring. Unlike regular leaderboards which are ongoing, tournaments have defined start/end times and often include multiple rounds or stages.

Key Concepts

Group Tournaments vs Leaderboards

Group Tournaments

  • Time-limited competitive events
  • Players must join to participate
  • Specific scoring windows and deadlines
  • Often have prizes or rewards
  • Results are finalized when tournament ends

Regular Leaderboards

  • Ongoing rankings without time limits
  • No joining required
  • Continuous score submission
  • Always active and updating

Tournament Structure

Tournaments in the Moitribe SDK can include:

Main Tournament

  • The primary competitive event
  • Has a unique tournament ID
  • Defined start and end times
  • Specific scoring rules

Sub-Tournaments

  • Nested competitions within the main event
  • Separate rankings and scoring
  • Can have different rules or timeframes
  • Share the same tournament context

Tournament States

Tournaments progress through these states:

  1. Upcoming - Tournament is announced but not started
  2. Active - Tournament is running, accepting scores
  3. Ended - Tournament finished, no more scores accepted
  4. Results - Final rankings are available

Tournament Workflow

Here's the typical flow for implementing tournaments:

// 1. Get tournament metadata to see available events
MoitribeSDK('my-game-id', 'groupTournamentMeta', {
callback: (result) => {
if (result.success) {
const tournaments = result.tournaments;
console.log('Available tournaments:', tournaments);
}
}
});

// 2. Get specific tournament details
MoitribeSDK('my-game-id', 'groupTournamentData', {
tournamentid: 'weekly-challenge-001',
callback: (result) => {
if (result.success) {
console.log('Tournament details:', result.tournament);
}
}
});

// 3. Join the tournament
MoitribeSDK('my-game-id', 'groupTournamentJoin', {
tournamentid: 'weekly-challenge-001',
callback: (result) => {
if (result.success) {
console.log('Successfully joined tournament');
}
}
});

// 4. Submit scores during the tournament
MoitribeSDK('my-game-id', 'groupTournamentScoreSubmit', {
tournamentid: 'weekly-challenge-001',
score: 1500,
callback: (result) => {
console.log('Score submitted:', result.success);
}
});

// 5. Get tournament results when finished
MoitribeSDK('my-game-id', 'groupTournamentResults', {
tournamentid: 'weekly-challenge-001',
callback: (result) => {
if (result.success) {
console.log('Final rankings:', result.rankings);
}
}
});

Available Operations

Get Tournament Metadata

Retrieve all available tournaments for your game:

MoitribeSDK('my-game-id', 'groupTournamentMeta', {
callback: (result) => {
// Returns list of available tournaments with basic info
}
});

See: Get Metadata

Get Tournament Data

Get detailed information about a specific tournament:

MoitribeSDK('my-game-id', 'groupTournamentData', {
tournamentid: 'tournament-id',
callback: (result) => {
// Returns full tournament details, rules, and schedule
}
});

See: Get Tournament Data

Join Tournament

Register a player to participate in a tournament:

MoitribeSDK('my-game-id', 'groupTournamentJoin', {
tournamentid: 'tournament-id',
callback: (result) => {
// Confirms player participation
}
});

See: Join Tournament

Submit Tournament Score

Submit a player's score during an active tournament:

MoitribeSDK('my-game-id', 'groupTournamentScoreSubmit', {
tournamentid: 'tournament-id',
score: 1000,
callback: (result) => {
// Confirms score submission
}
});

See: Submit Score

Get Tournament Results

Retrieve final rankings and results:

MoitribeSDK('my-game-id', 'groupTournamentResults', {
tournamentid: 'tournament-id',
callback: (result) => {
// Returns final rankings and participant data
}
});

See: Get Results

TypeScript Example

Use proper typing for type-safe tournament operations:

import MoitribeSDK from '@veniso/moitribe-js';

// Get tournament metadata with typing
MoitribeSDK('my-game-id', 'groupTournamentMeta', {
callback: (result: { success: boolean; tournaments: any[] }) => {
if (result.success) {
result.tournaments.forEach((tournament) => {
console.log(`${tournament.name} (${tournament.id})`);
console.log(`Status: ${tournament.status}`);
console.log(`Ends: ${new Date(tournament.endTime)}`);
});
}
}
});

// Join tournament with typing
MoitribeSDK('my-game-id', 'groupTournamentJoin', {
tournamentid: 'weekly-challenge-001',
callback: (result: { success: boolean; message?: string }) => {
if (result.success) {
console.log('Successfully joined tournament');
} else {
console.error('Failed to join:', result.message);
}
}
});

Common Use Cases

Weekly Challenge Tournament

Create a weekly competitive event:

function setupWeeklyChallenge() {
// Get this week's tournament
MoitribeSDK('my-game-id', 'groupTournamentMeta', {
callback: (result) => {
if (result.success) {
const weeklyTournament = result.tournaments.find(
t => t.type === 'weekly' && t.status === 'active'
);

if (weeklyTournament) {
joinWeeklyChallenge(weeklyTournament.id);
} else {
showMessage('No active weekly tournament');
}
}
}
});
}

function joinWeeklyChallenge(tournamentId) {
MoitribeSDK('my-game-id', 'groupTournamentJoin', {
tournamentid: tournamentId,
callback: (result) => {
if (result.success) {
showTournamentUI(tournamentId);
} else {
showError('Failed to join tournament');
}
}
});
}

Tournament Score Tracking

Track and display player's tournament progress:

class TournamentTracker {
constructor(tournamentId) {
this.tournamentId = tournamentId;
this.bestScore = 0;
}

submitScore(score) {
if (score > this.bestScore) {
this.bestScore = score;
}

MoitribeSDK('my-game-id', 'groupTournamentScoreSubmit', {
tournamentid: this.tournamentId,
score: score,
callback: (result) => {
if (result.success) {
this.updateScoreDisplay(score);
} else {
this.showError('Failed to submit score');
}
}
});
}

updateScoreDisplay(score) {
document.getElementById('current-score').textContent = score;
document.getElementById('best-score').textContent = this.bestScore;
}
}

// Usage
const tracker = new TournamentTracker('weekly-challenge-001');
tracker.submitScore(1500);

Tournament Status Checker

Check tournament status and handle different states:

function checkTournamentStatus(tournamentId) {
MoitribeSDK('my-game-id', 'groupTournamentData', {
tournamentid: tournamentId,
callback: (result) => {
if (result.success) {
const tournament = result.tournament;
handleTournamentState(tournament);
}
}
});
}

function handleTournamentState(tournament) {
const now = Date.now();
const startTime = new Date(tournament.startTime).getTime();
const endTime = new Date(tournament.endTime).getTime();

if (now < startTime) {
showTournamentCountdown(startTime);
} else if (now >= startTime && now < endTime) {
showActiveTournament(tournament);
} else {
showTournamentResults(tournament.id);
}
}

Tournament Data Structure

Tournament Metadata Response

interface TournamentMeta {
id: string; // 'weekly-challenge-001'
name: string; // 'Weekly Challenge'
description: string; // 'Compete for the top score this week'
type: string; // 'weekly', 'daily', 'special'
status: string; // 'upcoming', 'active', 'ended'
startTime: number; // Tournament start timestamp
endTime: number; // Tournament end timestamp
maxParticipants?: number; // Maximum allowed participants
currentParticipants: number; // Current participant count
}

Tournament Data Response

interface TournamentData {
id: string; // Tournament ID
name: string; // Tournament name
description: string; // Full description
rules: string; // Tournament rules and scoring
startTime: number; // Start timestamp
endTime: number; // End timestamp
status: string; // Current status
prizes?: Prize[]; // Prize information
subTournaments?: SubTournament[]; // Nested tournaments
participantCount: number; // Number of participants
scoreType: string; // 'high', 'low', 'time'
}

Tournament Results Response

interface TournamentResults {
tournamentId: string; // Tournament ID
endTime: number; // When tournament ended
totalParticipants: number; // Total participants
rankings: TournamentRanking[]; // Player rankings
playerRank?: number; // Current player's rank (if participated)
playerScore?: number; // Current player's score (if participated)
}

interface TournamentRanking {
rank: number; // Position (1, 2, 3...)
player: Player; // Player information
score: number; // Final score
timestamp: number; // When score was submitted
}

Authentication Requirements

warning

Players must be authenticated to join tournaments and submit scores. Viewing tournament results may work without authentication depending on your game's configuration.

Check authentication before tournament operations:

MoitribeSDK('my-game-id', 'isAuthenticated', {}, (authResult) => {
if (authResult.success) {
// Player is authenticated, can join tournament
MoitribeSDK('my-game-id', 'groupTournamentJoin', {
tournamentid: 'weekly-challenge-001',
callback: (result) => {
console.log('Joined tournament:', result.success);
}
});
} else {
// Prompt player to log in
showLoginPrompt();
}
});

Error Handling

Handle common tournament errors:

MoitribeSDK('my-game-id', 'groupTournamentJoin', {
tournamentid: 'weekly-challenge-001',
callback: (result) => {
if (result.success) {
console.log('Successfully joined tournament');
} else {
// Handle specific errors
if (result.msg.includes('authenticated')) {
showError('Please log in to join tournaments');
} else if (result.msg.includes('started')) {
showError('Tournament has already started');
} else if (result.msg.includes('ended')) {
showError('Tournament has ended');
} else if (result.msg.includes('full')) {
showError('Tournament is full');
} else {
showError('Failed to join tournament. Please try again.');
}
}
}
});

Next Steps

Learn about specific tournament operations:

Related topics: