Leaderboards Overview
Leaderboards allow you to create competitive rankings for your players, encouraging engagement and replay value. The Moitribe SDK provides flexible leaderboard functionality with social and global rankings, multiple timespans, and customizable scoring.
Key Concepts
Leaderboard Types
The Moitribe SDK supports two main types of leaderboards based on collections:
Social Leaderboards (Collection 0)
- Rankings among friends and social connections
- Encourages social gameplay and friend competition
- Smaller, more intimate competitive groups
Global Leaderboards (Collection 1)
- Rankings among all players worldwide
- Large-scale competition across your entire player base
- Best for competitive games with high player counts
Timespans
Each leaderboard can track scores across multiple time periods:
| Timespan | Value | Description | Best For |
|---|---|---|---|
| All-time | 0 | All scores since leaderboard creation | Lifetime achievements |
| Weekly | 1 | Scores from the current week | Regular competition |
| Daily | 2 | Scores from the current day | Quick challenges |
Use multiple timespans to give players different ways to compete. A player might not top the all-time board, but could win the daily challenge!
Score Ordering
Leaderboards support two ordering modes:
- Ascending (-1): Lower scores are better (speedruns, golf, time trials)
- Descending (1): Higher scores are better (points, kills, achievements)
The ordering is configured in your Moitribe dashboard and returned in leaderboard metadata.
Leaderboard Workflow
Here's the typical flow for implementing leaderboards:
// 1. Load leaderboard metadata to get configuration
MoitribeSDK('my-game-id', 'loadleaderboardmetadata', {
onlyData: true,
callback: (result) => {
if (result.success) {
const leaderboards = result.leaderboards;
console.log('Available leaderboards:', leaderboards);
}
}
});
// 2. Submit a score when player completes a level or match
MoitribeSDK('my-game-id', 'submitscore', {
leaderboardid: 'high-scores',
score: 1000,
scoretag: 'level-5',
callback: (result) => {
console.log('Score submitted:', result.success);
}
});
// 3. Retrieve and display top scores
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: 'high-scores',
collection: 1, // Global
timespan: 0, // All-time
maxresults: 10,
onlyData: true,
callback: (result) => {
if (result.success) {
result.scores.forEach((score, index) => {
console.log(`${index + 1}. ${score.playerName}: ${score.playerScore}`);
});
}
}
});
Available Operations
Load Leaderboard Metadata
Get configuration details for all your game's leaderboards:
MoitribeSDK('my-game-id', 'loadleaderboardmetadata', {
onlyData: true,
callback: (result) => {
// Returns leaderboard IDs, names, icons, and scoring rules
}
});
See: Get Metadata
Submit Scores
Post a player's score to a leaderboard:
MoitribeSDK('my-game-id', 'submitscore', {
leaderboardid: 'high-scores',
score: 1500,
scoretag: 'optional-metadata',
callback: (result) => {
console.log('Score submitted:', result.success);
}
});
See: Submit Score
Get Top Scores
Retrieve ranked scores from a leaderboard:
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: 'high-scores',
collection: 1, // Social (0) or Global (1)
timespan: 0, // All-time (0), Weekly (1), Daily (2)
maxresults: 10,
onlyData: true,
callback: (result) => {
// Returns array of scores with ranks and player info
}
});
See: Get Top Scores
TypeScript Example
Use proper typing for type-safe leaderboard operations:
import MoitribeSDK from '@veniso/moitribe-js';
import type { LeaderboardMeta, LeaderboardScoreData } from '@veniso/moitribe-js';
// Load metadata with typing
MoitribeSDK('my-game-id', 'loadleaderboardmetadata', {
onlyData: true,
callback: (result: { success: boolean; leaderboards: LeaderboardMeta[] }) => {
if (result.success) {
result.leaderboards.forEach((lb: LeaderboardMeta) => {
console.log(`${lb.leaderboardName} (${lb.leaderboardID})`);
console.log(`Order: ${lb.leaderboardScoreOrder === 1 ? 'Descending' : 'Ascending'}`);
});
}
}
});
// Get scores with typing
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: 'high-scores',
collection: 1,
timespan: 0,
maxresults: 10,
onlyData: true,
callback: (result: { success: boolean; scores: LeaderboardScoreData[] }) => {
if (result.success) {
result.scores.forEach((score: LeaderboardScoreData) => {
console.log(`#${score.playerRank}: ${score.playerName} - ${score.playerScore}`);
});
}
}
});
Common Use Cases
Display Multiple Timespans
Show daily, weekly, and all-time rankings:
function loadLeaderboard(leaderboardId, timespan) {
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: leaderboardId,
collection: 1,
timespan: timespan,
maxresults: 10,
onlyData: true,
callback: (result) => {
if (result.success) {
displayScores(result.scores, getTimespanName(timespan));
}
}
});
}
function getTimespanName(timespan) {
const names = { 0: 'All-Time', 1: 'This Week', 2: 'Today' };
return names[timespan] || 'Unknown';
}
// Load all timespans
loadLeaderboard('high-scores', 0); // All-time
loadLeaderboard('high-scores', 1); // Weekly
loadLeaderboard('high-scores', 2); // Daily
Social vs Global Toggle
Let players switch between friend and global rankings:
function loadLeaderboardByCollection(leaderboardId, isSocial) {
const collection = isSocial ? 0 : 1;
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: leaderboardId,
collection: collection,
timespan: 0,
maxresults: 10,
onlyData: true,
callback: (result) => {
if (result.success) {
const title = isSocial ? 'Friends Rankings' : 'Global Rankings';
displayScores(result.scores, title);
}
}
});
}
// Button handlers
document.getElementById('btn-friends').onclick = () => {
loadLeaderboardByCollection('high-scores', true);
};
document.getElementById('btn-global').onclick = () => {
loadLeaderboardByCollection('high-scores', false);
};
Submit Score with Metadata
Use scoretag to store additional information:
function submitGameScore(score, level, difficulty) {
// Store metadata as JSON string
const metadata = JSON.stringify({
level: level,
difficulty: difficulty,
timestamp: Date.now()
});
MoitribeSDK('my-game-id', 'submitscore', {
leaderboardid: 'high-scores',
score: score,
scoretag: metadata,
callback: (result) => {
if (result.success) {
console.log('Score submitted with metadata');
}
}
});
}
// Submit score with context
submitGameScore(1500, 5, 'hard');
Leaderboard Data Structure
Metadata Response
interface LeaderboardMeta {
leaderboardID: string; // 'high-scores'
leaderboardName: string; // 'High Scores'
leaderboardIconURL: string; // URL to icon image
leaderboardScoreOrder: number; // 1 (descending) or -1 (ascending)
leaderboardCollection: {
Social: number; // Social collection ID
All: number; // Global collection ID
};
}
Score Data Response
interface LeaderboardScoreData {
playerRank: number; // Player's position (1, 2, 3...)
playerScore: number; // The actual score
playerName: string; // Player's display name
leaderboardID: string; // ID of this leaderboard
timestamp: number; // When score was submitted
player: Player; // Full player object
iconURL: string; // Player's profile icon
hiresURL: string; // High-resolution profile image
scoreTag: string; // Custom metadata
}
Authentication Requirements
Players must be authenticated to submit scores and view social leaderboards. Global leaderboard viewing may work without authentication depending on your game's configuration.
Check authentication before submitting scores:
MoitribeSDK('my-game-id', 'isAuthenticated', {}, (authResult) => {
if (authResult.success) {
// Player is authenticated, submit score
MoitribeSDK('my-game-id', 'submitscore', {
leaderboardid: 'high-scores',
score: 1000,
callback: (result) => {
console.log('Score submitted:', result.success);
}
});
} else {
// Prompt player to log in
showLoginPrompt();
}
});
Error Handling
Handle common leaderboard errors:
MoitribeSDK('my-game-id', 'submitscore', {
leaderboardid: 'high-scores',
score: 1000,
callback: (result) => {
if (result.success) {
console.log('Score submitted successfully');
} else {
// Handle specific errors
if (result.msg.includes('authenticated')) {
showError('Please log in to submit scores');
} else if (result.msg.includes('leaderboard')) {
showError('Leaderboard not found');
} else {
showError('Failed to submit score. Please try again.');
}
}
}
});
Next Steps
Learn about specific leaderboard operations:
- Get Metadata - Load leaderboard configuration
- Submit Score - Post player scores
- Get Top Scores - Retrieve rankings
- Score Collections - Social vs Global explained
- Timespans - Daily, Weekly, All-time rankings
- Best Practices - Implementation tips
Related topics:
- Authentication - Required for score submission
- Profiles - Player data in leaderboards
- Tournaments - Competitive events