Advanced Features
Deep dive into the SDK's architecture, API, and advanced capabilities
Core Architecture
RankoraPlayer
Manages current player data, score submission, and synchronization
RankoraLeaderboard
Handles leaderboard display, pagination, and data management
RankoraEvents
Central event bus for component communication and data flow
Data Flow
Player Score Submission → Events → Leaderboard Update → UI Refresh
The system uses a reactive architecture where changes automatically propagate through events.
Core Classes Reference
Key Properties
PlayerName
- Current player name (get/set)Score
- Current score (get/set)Rank
- Current leaderboard rank (read-only)PlayerId
- Unique player identifier (read-only)Metadata
- Custom key-value data (get/set)
Core Methods
Get()
- Load or create playerSync(callback)
- Submit data to serverRefreshPlayerData()
- Fetch latest dataDeleteCurrentPlayer()
- Remove player
using Rankora_API.Scripts.Rankora.Main;
using Rankora_API.Scripts.Rankora.Types;
public class PlayerManager : MonoBehaviour
{
void Start() {
// Listen for player updates
RankoraPlayer.Instance.OnPlayerUpdate.Subscribe(player => {
Debug.Log($"Player updated: {player.PlayerName} - Score: {player.Score} - Rank: {player.Rank}");
UpdatePlayerUI(player);
});
// Load existing player data
RankoraPlayer.Instance.Get();
}
// Called when player completes a level/game
public void SubmitScore(string playerName, int newScore) {
// Update player properties
RankoraPlayer.Instance.PlayerName = playerName;
RankoraPlayer.Instance.Score = newScore;
// Add custom metadata
RankoraPlayer.Instance.Metadata.Set("level", GetCurrentLevel());
RankoraPlayer.Instance.Metadata.Set("gameMode", "arcade");
RankoraPlayer.Instance.Metadata.Set("playTime", GetPlayTimeSeconds());
// Submit to server with callback
RankoraPlayer.Instance.Sync((response) => {
if (response.success) {
Debug.Log($"Score submitted successfully! New rank: {response.rank}");
ShowSuccessMessage($"Great! You're now rank #{response.rank}");
} else {
Debug.LogError($"Failed to submit score: {response.error}");
ShowErrorMessage("Failed to submit score. Please try again.");
}
});
}
private void UpdatePlayerUI(RankoraPlayer player) {
// Update your UI elements here
playerNameText.text = player.PlayerName;
scoreText.text = player.Score.ToString("N0");
rankText.text = player.Rank > 0 ? $"#{player.Rank}" : "Unranked";
}
}
UI Integration
The SDK is designed to work with any UI system. Here's how to integrate it:
public class LeaderboardUI : MonoBehaviour
{
[Header("UI Elements")]
[SerializeField] private Transform entriesContainer;
[SerializeField] private TextMeshProUGUI messageText;
[SerializeField] private GameObject loadingSpinner;
[Header("Entry Prefab")]
public GameObject entryPrefab; // Your custom entry prefab
void Start() {
// Listen for leaderboard updates
RankoraLeaderboard.Instance.OnEntriesUpdated.Subscribe(entries => {
UpdateLeaderboardUI(entries);
});
// Listen for errors
RankoraLeaderboard.Instance.OnError.Subscribe(error => {
ShowMessage(error);
});
// Fetch initial data
RankoraLeaderboard.Instance.GetCurrentPage();
}
private void UpdateLeaderboardUI(List<LeaderboardEntry> entries) {
// Clear existing entries
foreach (Transform child in entriesContainer) {
Destroy(child.gameObject);
}
// Create new entry UIs
foreach (var entry in entries) {
var entryUI = Instantiate(entryPrefab, entriesContainer);
// Configure your entry UI component here
ConfigureEntryUI(entryUI, entry);
}
}
private void ConfigureEntryUI(GameObject entryUI, LeaderboardEntry entry) {
// Set up your entry UI with the entry data
// This depends on your UI component structure
}
private void ShowMessage(string message) {
messageText.text = message;
messageText.gameObject.SetActive(!string.IsNullOrEmpty(message));
}
}
Advanced patterns for building production-ready leaderboard UIs:
Best Practices:
- • Use object pooling for entry UIs
- • Implement loading states and error handling
- • Add pagination controls
- • Handle offline scenarios gracefully
- • Use Canvas Groups for smooth transitions
API Integration & Authentication
Authentication Methods
- Bearer Token:
Authorization: Bearer YOUR_API_KEY
- Configured once in RankoraSettings
- Automatically applied to all requests
- Secure HTTPS communication
API Endpoints
- GET /usage - Check API limits
- GET /leaderboard - Leaderboard metadata
- GET /leaderboard/entries - Fetch entries
- POST /leaderboard/entries - Submit scores
Data Validation & Limits
Player Data Validation:
- • Player names must pass validation rules
- • Scores must be finite numbers
- • Player IDs must be valid UUIDs
Metadata Rules:
- • Maximum 10 metadata keys
- • Key length: max 32 characters
- • Value length: max 64 characters
Direct API Usage
Core API Methods
GetLeaderboardMetadata()
- Fetch leaderboard infoGetLeaderboardEntries()
- Fetch leaderboard entriesCreateOrUpdatePlayerEntry()
- Submit player dataGetEntryById()
- Fetch specific player
Error Handling
OnError
- Global error event- Automatic network error detection
- Validation error handling
- User-friendly error messages
using Rankora_API.Scripts.Rankora.Api;
using Rankora_API.Scripts.Rankora.Types;
public class CustomAPIManager : MonoBehaviour
{
void Start() {
// Listen for global errors
RankoraClient.OnError.Subscribe(errorMessage => {
Debug.LogError($"API Error: {errorMessage}");
ShowErrorMessage(errorMessage);
});
// Fetch leaderboard metadata
RankoraClient.GetLeaderboardMetadata(
onSuccess: metadata => {
Debug.Log($"Leaderboard: {metadata.name}");
Debug.Log($"Total entries: {metadata.total_entries}");
},
onError: error => {
Debug.LogError($"Failed to fetch metadata: {error}");
}
);
// Fetch specific page of entries
var query = new EntriesQuery {
Skip = 0,
PageSize = 10
};
RankoraClient.GetLeaderboardEntries(query,
onSuccess: response => {
if (response.success && response.entries != null) {
Debug.Log($"Fetched {response.entries.Length} entries");
ProcessEntries(response.entries);
}
},
onError: error => {
Debug.LogError($"Failed to fetch entries: {error}");
}
);
}
private void ProcessEntries(LeaderboardEntry[] entries) {
// Process the entries
}
private void ShowErrorMessage(string error) {
// Show error to user
}
}
Performance & Optimization
Automatic Caching
- • Page results cached for 5 seconds
- • Player data cached locally
- • Smart cache invalidation
- • Memory-efficient storage
Tip: The SDK automatically manages cache lifecycle. Manual refresh is only needed for real-time updates.
Built-in Safeguards
- • Automatic event unsubscription
- • Efficient data structures
- • Minimal memory footprint
- • Garbage collection optimization
Best Practice: Always unsubscribe from events when components are destroyed to prevent memory leaks.
UI Optimization
- • Use object pooling for entry UIs
- • Minimize UI rebuilds
- • Batch UI updates
- • Use Canvas Groups for visibility
API Usage
- • Avoid excessive API calls
- • Use appropriate page sizes
- • Implement request debouncing
- • Handle offline scenarios gracefully
Troubleshooting & Debugging
API Connection Issues
- • Verify API key is correct in settings
- • Check internet connection
- • Verify API key has proper permissions
- • Check Unity console for error messages
Data Not Updating
- • Check event subscriptions are active
- • Verify UI components are properly connected
- • Ensure events are being raised correctly
- • Check for null reference exceptions
Build Errors
- • Check assembly definition references
- • Verify all required packages are installed
- • Clean and rebuild project
- • Check for missing dependencies