Prerequisites
- Phaser 3 project (any bundler or plain
<script>tag) - A LightLeaderboard account, game, and API key
- A modern browser —
fetchandcrypto.randomUUID()are natively available
CORS: LightLeaderboard's API allows browser requests from any origin.
No proxy needed.
Submit a Score
Call submitScore when the game ends. The response contains the player's new rank —
show it immediately in your game-over screen.
// Call this from your GameOver scene or score handler
async function submitScore(score, playerId, playerName) {
const res = await fetch(
"https://yourapp.com/api/v1/games/my_game/scores",
{
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
score,
playerRefId: playerId,
playerName,
submissionId: crypto.randomUUID(),
}),
}
);
return res.json(); // → { rank: 3, score: 42000, playerName: "Alice" }
}Use in a Phaser Scene
Mark your scene method async and await the result.
Phaser scenes handle async methods fine — the scene won't freeze.
// Inside a Phaser 3 Scene class
class GameOverScene extends Phaser.Scene {
async showRank(score, playerId, playerName) {
const data = await submitScore(score, playerId, playerName);
this.add.text(400, 300,
`You ranked #${data.rank}!`,
{ fontSize: "32px", color: "#a89cff" }
).setOrigin(0.5);
}
}Fetch & Display the Leaderboard
Fetch the top 10 in your leaderboard scene's create(). Render each entry
with this.add.text().
// Fetch and display top 10
async function getLeaderboard() {
const res = await fetch(
"https://yourapp.com/api/v1/games/my_game/leaderboard?limit=10",
{
headers: { "Authorization": "Bearer YOUR_API_KEY" },
}
);
const { entries } = await res.json();
return entries; // [{ rank, playerName, score }, ...]
}
// In a Phaser scene:
class LeaderboardScene extends Phaser.Scene {
async create() {
const entries = await getLeaderboard();
entries.forEach((e, i) => {
this.add.text(50, 80 + i * 36,
`#${e.rank} ${e.playerName} ${e.score}`,
{ fontSize: "18px", color: "#ffffff" }
);
});
}
}Tips
- Store your API key in a
config.jsfile — never commit it to a public repo. For client-side games, consider routing submissions through your own backend if you want to keep the key secret. - Use
crypto.randomUUID()forsubmissionId. This prevents duplicate submissions on retry. Falls back toDate.now().toString()in very old browsers. - Add
?period=weeklyto the leaderboard URL for weekly reset rankings. - Pass
seasonIdin the score body to support tournament seasons.