SDK / Beta
Leaderboards
Add casual, public score rankings with authenticated personal bests and platform-approved leaderboard keys.
Install the SDK
SDK v3 is recommended for new games and retains the existing Leaderboards API. SDK v2 remains supported for existing integrations.
The canonical artifact is /sdk/v2/3jsgames.js. Download it unchanged and vendor it in an uploaded game as 3jsgames-sdk/v2/3jsgames.js.
<script src="./3jsgames-sdk/v2/3jsgames.js"></script>SDK v2 includes both ThreeJSGames.storage and ThreeJSGames.leaderboards. Historical Storage-only integrations may continue using SDK v1.
Prerequisites
- Create the intended leaderboard key from the game's creator dashboard, choose its integer score range, and enable it before publishing.
- Disable a leaderboard before changing its key or score range. Those fields stay locked once scores exist, and leaderboards with score history cannot be deleted.
- Keep the exact approved SDK bytes and upload-compatible path shown above.
Public API
ThreeJSGames.leaderboards.submit(key, score)ThreeJSGames.leaderboards.getTop(key, options?)ThreeJSGames.leaderboards.getPersonal(key)ThreeJSGames.leaderboards.isAvailable()
Copy-ready examples
Submit a score
const result = await ThreeJSGames.leaderboards.submit("global", score);
if (result.improved) {
console.log("New personal best:", result.bestScore);
}Read Top
const result = await ThreeJSGames.leaderboards.getTop("global", {
limit: 10
});
for (const entry of result.entries) {
console.log(entry.rank, entry.player.displayName, entry.score);
}Read the current player's best
const result = await ThreeJSGames.leaderboards.getPersonal("global");
if (result.personal) {
console.log(result.personal.rank, result.personal.score);
}Check platform availability
if (ThreeJSGames.leaderboards.isAvailable()) {
// Running inside the supported 3JSGames environment.
}isAvailable() only confirms the supported embedded environment. It does not guarantee an authenticated user, an approved leaderboard key, or network availability.
Complete minimal game-over integration
This example keeps standalone play intact, loads public rankings anonymously, submits only at game over, and separates signed-out, unavailable, empty, and transient failure states.
const board = ThreeJSGames?.leaderboards;
const key = "global"; // Must be approved and enabled for this game.
function showStatus(message) {
document.querySelector("#leaderboard-status").textContent = message;
}
async function refreshTop() {
if (!board?.isAvailable()) {
showStatus("Scores are unavailable outside 3JSGames.");
return;
}
showStatus("Loading scores…");
try {
const result = await board.getTop(key, { limit: 10 });
showStatus(result.entries.length ? "Scores loaded." : "No scores yet.");
// Render result.entries using textContent, not innerHTML.
} catch (error) {
showStatus(error.code === "LEADERBOARD_NOT_AVAILABLE"
? "This leaderboard is not enabled."
: "Scores could not be loaded. Retry later.");
}
}
async function submitGameOverScore(finalScore) {
if (!board?.isAvailable()) return; // Keep standalone gameplay working.
try {
const result = await board.submit(key, finalScore);
showStatus(result.improved ? "New personal best!" : "Score submitted.");
await refreshTop();
} catch (error) {
if (error.code === "AUTH_REQUIRED") {
showStatus("Sign in to submit. Public scores are still available.");
} else {
showStatus("Submission failed. Keep the game result and offer retry.");
}
}
}
refreshTop();Platform-approved keys
Leaderboard keys are explicitly configured and enabled by the game creator during Beta. Calling submit("whatever", score) cannot create an arbitrary public leaderboard. A missing or disabled key returns LEADERBOARD_NOT_AVAILABLE.
Design the intended keys before integration. Names such as global, endless, and hard are examples only; they are not automatically enabled.
Score semantics
- A score must be a JavaScript safe integer.
- Higher scores are better; lower-is-better is not supported.
- Each user has one best score per leaderboard.
- Equal or lower submissions do not replace the current best or its timestamp.
- A personal best follows the same signed-in account across supported devices.
- Top ordering is deterministic.
Stable errors
Branch on error.code, never message text.
AUTH_REQUIRED means the operation needs a signed-in 3JSGames player; it is distinct from LEADERBOARD_NOT_AVAILABLE (the key is not enabled) and LEADERBOARD_UNAVAILABLE (the service or embedded bridge cannot currently be used). Authentication and game identity are supplied by the platform; games must never request or send IDs or credentials.
What games must not do
- Do not connect to Supabase or platform database tables.
- Do not call leaderboard HTTP routes directly or recreate the SDK with raw
postMessage. - Do not send player IDs, game IDs, authorization headers, context tokens, or service credentials.
- Do not modify the vendored SDK bytes or assume an arbitrary key creates a leaderboard.
Copy-ready AI integration prompt
Integrate the existing 3JSGames Leaderboards Beta SDK into this standalone HTML5 game.
1. Preserve the existing game architecture and standalone gameplay.
2. Vendor the unchanged official SDK v3 at 3jsgames-sdk/v3/3jsgames.js and load it with ./3jsgames-sdk/v3/3jsgames.js before the game script. Existing SDK v2 integrations remain supported.
3. Use only ThreeJSGames.leaderboards.submit(key, score), getTop(key, { limit }), getPersonal(key), and isAvailable().
4. Use only this platform-approved leaderboard key: global. Do not create or guess keys.
5. Submit the final JavaScript safe-integer score once at game over. Higher scores are better and the platform keeps one personal best.
6. Show explicit loading, empty, unavailable, signed-out, failure, and retry states. A failed submission must not discard or crash the game result.
7. Treat AUTH_REQUIRED as a sign-in state; public getTop reads may still work. Branch on error.code, never message text.
8. Do not call Supabase or private platform endpoints, access window.parent, write raw postMessage transport, send player/game IDs, modify the SDK, or add credentials.
9. Render public player fields safely and do not treat browser-submitted scores as cheat-proof.
10. Test standalone behavior and the uploaded-game SDK/iframe bridge path.Beta boundaries
Available in Beta
- Authenticated score submission
- One personal best per user and leaderboard
- Global top-N rankings
- Personal rank and best lookup
- Public anonymous leaderboard reads
- Approved leaderboard keys only
- Creator dashboard leaderboard configuration
- Higher-is-better integer scores
- Cross-device account persistence
Not supported yet
- Lower-is-better rankings
- Seasons
- Score history
- Realtime updates
- Team rankings
- Verified or cheat-proof scores
- Prize-bearing competitive use