Score Collections
Leaderboard collections determine which group of players are ranked together. The Moitribe SDK supports two collection types: Social (friends only) and Global (all players).
Collection Types
Social Collection (Value: 0)
Shows rankings among friends and social connections:
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: 'high-scores',
collection: 0, // Social collection
timespan: 0,
maxresults: 10,
onlyData: true,
callback: (result) => {
console.log('Friend rankings:', result.scores);
}
});
Characteristics:
- Only includes players in the viewer's social network
- Smaller, more intimate competitive groups
- Encourages social gameplay and friend invitations
- Requires authentication to view
Best for:
- Social games with friend systems
- Encouraging friend competition
- Viral mechanics ("Beat your friends!")
- Personal milestone tracking
Global Collection (Value: 1)
Shows rankings among all players worldwide:
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: 'high-scores',
collection: 1, // Global collection
timespan: 0,
maxresults: 10,
onlyData: true,
callback: (result) => {
console.log('Global rankings:', result.scores);
}
});
Characteristics:
- Includes all players across your entire game
- Large-scale competition
- Shows true world rankings
- May not require authentication to view (game-dependent)
Best for:
- Competitive games
- Showcasing top players
- Global challenges
- Esports and tournaments
Collection Parameter
The collection parameter is used when loading leaderboard scores:
| Value | Type | Description |
|---|---|---|
0 | Social | Friends and connections only |
1 | Global | All players worldwide |
interface LoadScoresParams {
leaderboardid: string;
collection: 0 | 1; // Social or Global
timespan: 0 | 1 | 2;
maxresults?: number;
onlyData: boolean;
callback: (result: ScoresResult) => void;
}
Common Use Cases
Toggle Between Collections
Let players switch between friend and global rankings:
let currentCollection = 1; // Start with global
function toggleCollection() {
// Switch between collections
currentCollection = currentCollection === 1 ? 0 : 1;
// Update button text
const buttonText = currentCollection === 1 ? 'Show Friends' : 'Show Global';
document.getElementById('toggle-btn').textContent = buttonText;
// Reload leaderboard
loadLeaderboard('high-scores', currentCollection);
}
function loadLeaderboard(leaderboardId, collection) {
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: leaderboardId,
collection: collection,
timespan: 0,
maxresults: 10,
onlyData: true,
callback: (result) => {
if (result.success) {
const title = collection === 0 ? 'Friends Rankings' : 'Global Rankings';
displayScores(result.scores, title);
}
}
});
}
// Button click handler
document.getElementById('toggle-btn').onclick = toggleCollection;
Tabbed Interface
Create tabs for social and global views:
function setupCollectionTabs(leaderboardId) {
// Social tab
document.getElementById('tab-friends').onclick = () => {
setActiveTab('tab-friends');
loadLeaderboard(leaderboardId, 0);
};
// Global tab
document.getElementById('tab-global').onclick = () => {
setActiveTab('tab-global');
loadLeaderboard(leaderboardId, 1);
};
// Load global by default
setActiveTab('tab-global');
loadLeaderboard(leaderboardId, 1);
}
function setActiveTab(tabId) {
document.querySelectorAll('.tab').forEach(tab => {
tab.classList.remove('active');
});
document.getElementById(tabId).classList.add('active');
}
function loadLeaderboard(leaderboardId, collection) {
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: leaderboardId,
collection: collection,
timespan: 0,
maxresults: 10,
onlyData: true,
callback: (result) => {
if (result.success) {
displayScores(result.scores);
}
}
});
}
// Initialize
setupCollectionTabs('high-scores');
Side-by-Side Comparison
Display social and global rankings together:
function loadBothCollections(leaderboardId) {
// Load social rankings
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: leaderboardId,
collection: 0,
timespan: 0,
maxresults: 5,
onlyData: true,
callback: (result) => {
if (result.success) {
displayScores(result.scores, 'friends-leaderboard', 'Friends');
}
}
});
// Load global rankings
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: leaderboardId,
collection: 1,
timespan: 0,
maxresults: 5,
onlyData: true,
callback: (result) => {
if (result.success) {
displayScores(result.scores, 'global-leaderboard', 'Global');
}
}
});
}
function displayScores(scores, containerId, title) {
const container = document.getElementById(containerId);
container.innerHTML = `<h3>${title}</h3>`;
scores.forEach((score) => {
const row = document.createElement('div');
row.innerHTML = `${score.playerRank}. ${score.playerName}: ${score.playerScore}`;
container.appendChild(row);
});
}
// Display both
loadBothCollections('high-scores');
Collection Selector Dropdown
Use a dropdown to select collection:
function setupCollectionDropdown(leaderboardId) {
const selector = document.getElementById('collection-selector');
// Add options
selector.innerHTML = `
<option value="1">Global Rankings</option>
<option value="0">Friends Rankings</option>
`;
// Handle change
selector.onchange = (e) => {
const collection = parseInt(e.target.value);
loadLeaderboard(leaderboardId, collection);
};
// Load global by default
loadLeaderboard(leaderboardId, 1);
}
function loadLeaderboard(leaderboardId, collection) {
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: leaderboardId,
collection: collection,
timespan: 0,
maxresults: 10,
onlyData: true,
callback: (result) => {
if (result.success) {
displayScores(result.scores);
}
}
});
}
// Initialize
setupCollectionDropdown('high-scores');
TypeScript Collection Manager
Create a type-safe collection manager:
import MoitribeSDK from '@veniso/moitribe-js';
import type { LeaderboardScoreData } from '@veniso/moitribe-js';
enum CollectionType {
Social = 0,
Global = 1
}
interface CollectionOptions {
leaderboardId: string;
collection: CollectionType;
timespan?: 0 | 1 | 2;
maxResults?: number;
}
class LeaderboardCollectionManager {
private gameId: string;
private currentCollection: CollectionType = CollectionType.Global;
constructor(gameId: string) {
this.gameId = gameId;
}
async loadScores(options: CollectionOptions): Promise<LeaderboardScoreData[]> {
return new Promise((resolve, reject) => {
MoitribeSDK(this.gameId, 'loadleaderboardtopscores', {
leaderboardid: options.leaderboardId,
collection: options.collection,
timespan: options.timespan || 0,
maxresults: options.maxResults || 10,
onlyData: true,
callback: (result: { success: boolean; scores: LeaderboardScoreData[] }) => {
if (result.success) {
this.currentCollection = options.collection;
resolve(result.scores);
} else {
reject(new Error('Failed to load scores'));
}
}
});
});
}
async loadSocialScores(leaderboardId: string): Promise<LeaderboardScoreData[]> {
return this.loadScores({
leaderboardId,
collection: CollectionType.Social
});
}
async loadGlobalScores(leaderboardId: string): Promise<LeaderboardScoreData[]> {
return this.loadScores({
leaderboardId,
collection: CollectionType.Global
});
}
toggleCollection(): CollectionType {
this.currentCollection = this.currentCollection === CollectionType.Global
? CollectionType.Social
: CollectionType.Global;
return this.currentCollection;
}
getCurrentCollection(): CollectionType {
return this.currentCollection;
}
getCollectionName(collection: CollectionType): string {
return collection === CollectionType.Social ? 'Friends' : 'Global';
}
}
// Usage
const manager = new LeaderboardCollectionManager('my-game-id');
// Load global scores
const globalScores = await manager.loadGlobalScores('high-scores');
console.log('Global scores:', globalScores);
// Load friend scores
const friendScores = await manager.loadSocialScores('high-scores');
console.log('Friend scores:', friendScores);
// Toggle between collections
const newCollection = manager.toggleCollection();
console.log('Switched to:', manager.getCollectionName(newCollection));
Collection Availability
Checking Collection Support
Verify which collections a leaderboard supports:
function checkCollectionSupport(leaderboardId) {
MoitribeSDK('my-game-id', 'loadleaderboardmetadata', {
onlyData: true,
callback: (result) => {
if (result.success) {
const leaderboard = result.leaderboards.find(
lb => lb.leaderboardID === leaderboardId
);
if (leaderboard) {
console.log('Social collection ID:', leaderboard.leaderboardCollection.Social);
console.log('Global collection ID:', leaderboard.leaderboardCollection.All);
// Both collections should be available if properly configured
const hasSocial = !!leaderboard.leaderboardCollection.Social;
const hasGlobal = !!leaderboard.leaderboardCollection.All;
console.log('Supports social:', hasSocial);
console.log('Supports global:', hasGlobal);
}
}
}
});
}
Social Collection Requirements
Authentication
Social collections require player authentication:
function loadSocialLeaderboard(leaderboardId) {
// Check authentication first
MoitribeSDK('my-game-id', 'isAuthenticated', {}, (authResult) => {
if (authResult.success) {
// Player is authenticated, load social rankings
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: leaderboardId,
collection: 0,
timespan: 0,
maxresults: 10,
onlyData: true,
callback: (result) => {
if (result.success) {
displayFriendRankings(result.scores);
}
}
});
} else {
// Show login prompt
showMessage('Please log in to view friend rankings');
showLoginButton();
}
});
}
Empty Social Rankings
Handle cases where player has no friends:
function displayFriendRankings(scores) {
if (scores.length === 0) {
showEmptyState(
'No friend scores yet',
'Invite friends to compete on the leaderboard!'
);
} else {
displayScores(scores);
}
}
function showEmptyState(title, message) {
const container = document.getElementById('leaderboard');
container.innerHTML = `
<div class="empty-state">
<h3>${title}</h3>
<p>${message}</p>
<button onclick="showInviteDialog()">Invite Friends</button>
</div>
`;
}
Best Practices
1. Default to Global
Start with global rankings for better initial experience:
// Good: Show global rankings first
function initializeLeaderboard(leaderboardId) {
loadLeaderboard(leaderboardId, 1); // Global
}
// Then allow switching to social
function showFriendRankings() {
loadLeaderboard(leaderboardId, 0); // Social
}
2. Indicate Current Collection
Make it clear which collection is displayed:
function displayScoresWithHeader(scores, collection) {
const title = collection === 0
? 'Friends Rankings'
: 'Global Rankings';
const subtitle = collection === 0
? 'Compete with your friends'
: 'See where you rank worldwide';
const container = document.getElementById('leaderboard');
container.innerHTML = `
<div class="leaderboard-header">
<h2>${title}</h2>
<p>${subtitle}</p>
</div>
`;
// Add scores...
}
3. Encourage Social Play
Prompt players to view friend rankings:
function showSocialPrompt() {
if (hasAuthenticatedFriends()) {
showNotification('See how you rank against your friends!', () => {
loadLeaderboard('high-scores', 0);
});
}
}
4. Handle Collection Errors
Gracefully handle unavailable collections:
function loadCollectionSafely(leaderboardId, collection) {
MoitribeSDK('my-game-id', 'loadleaderboardtopscores', {
leaderboardid: leaderboardId,
collection: collection,
timespan: 0,
maxresults: 10,
onlyData: true,
callback: (result) => {
if (result.success) {
displayScores(result.scores);
} else {
// Fall back to global if social fails
if (collection === 0) {
console.log('Social collection unavailable, showing global');
loadCollectionSafely(leaderboardId, 1);
} else {
showError('Unable to load leaderboard');
}
}
}
});
}
Collection Strategies
Beginner-Friendly
Start players with friend rankings:
function showBeginnerLeaderboard() {
// New players see friends first (less intimidating)
loadLeaderboard('high-scores', 0);
// Offer global view as option
showButton('View Global Rankings', () => {
loadLeaderboard('high-scores', 1);
});
}
Competitive Focus
Emphasize global rankings:
function showCompetitiveLeaderboard() {
// Competitive players see global first
loadLeaderboard('high-scores', 1);
// Friends view is secondary
showSmallButton('View Friends', () => {
loadLeaderboard('high-scores', 0);
});
}
Balanced Approach
Show both equally:
function showBalancedLeaderboard() {
// Show both with equal prominence
setupTabs(['Global', 'Friends'], [1, 0]);
// Default to player's preference
const preferredCollection = getPlayerPreference() || 1;
loadLeaderboard('high-scores', preferredCollection);
}
Next Steps
- Timespans - Daily, Weekly, and All-time rankings
- Get Top Scores - Loading leaderboard data
- Best Practices - Leaderboard implementation tips
Related topics:
- Authentication Overview - Required for social rankings
- Profiles - Friend connections
- Leaderboards Overview - Complete guide