Poplay SDK Integration Guide
This guide explains the minimum integration required before submitting an HTML5, Canvas, or WebGL game to Poplay.
1. Package Structure
Upload a ZIP package that can run as a static web game.
index.html
assets/
game.js
poplay.config.json
Requirements:
- Put
index.htmlin the package root. - Use relative asset paths.
- Make sure the game can run inside an iframe.
- Do not hardcode leaderboard, cloud save, or realtime service URLs.
- Put
poplay.config.jsonnext toindex.html.
2. Add the SDK
Add the SDK script in index.html.
<script src="https://poplay.io/sdk/poplay-sdk.js"></script>
Initialize Poplay before calling platform APIs.
await Poplay.init();
3. Player
const player = await Poplay.player.get();
console.log(player.id);
console.log(player.displayName);
console.log(player.locale);
4. Leaderboard
Declare a leaderboard in poplay.config.json.
{
"capabilities": {
"leaderboard": true
},
"leaderboards": [
{
"id": "global",
"name": "Global",
"sort": "desc",
"keepBest": true
}
]
}
Submit a score after a round ends.
await Poplay.leaderboard.submit("global", {
score: 12800,
metadata: {
level: 7,
duration: 93.2
}
});
Read leaderboard entries.
const entries = await Poplay.leaderboard.list("global", {
limit: 20
});
Read the current player's entry.
const me = await Poplay.leaderboard.me("global");
Rules:
- Submit scores only after meaningful gameplay events.
- Do not submit every frame or every second.
scoremust be a number.- Keep
metadatasmall.
5. Cloud Save
Declare cloud save in poplay.config.json.
{
"capabilities": {
"cloudSave": true
},
"save": {
"slots": ["default"],
"maxBytes": 65536
}
}
Load save data.
const save = await Poplay.save.get("default");
if (save) {
restoreProgress(save);
}
Write save data.
await Poplay.save.set("default", {
level: 12,
exp: 3400,
skins: ["red", "gold"],
settings: {
sound: true
}
});
Delete save data.
await Poplay.save.delete("default");
Rules:
- Save data must be JSON.
- Default save limit is 64KB.
- Do not store images, audio, or large level bundles in cloud save.
6. Realtime Rooms
Declare realtime rooms in poplay.config.json.
{
"capabilities": {
"realtime": true
},
"realtime": {
"maxPlayers": 2,
"visibility": "public",
"hostStrategy": "close-on-host-leave"
}
}
Quick match.
const room = await Poplay.rooms.quickMatch({
maxPlayers: 2
});
Create a public room.
const room = await Poplay.rooms.create({
maxPlayers: 2,
visibility: "public"
});
Join a room.
const rooms = await Poplay.rooms.list();
const room = await Poplay.rooms.join(rooms[0].id);
Send realtime messages.
room.broadcast("player-state", {
x: player.x,
y: player.y,
direction: player.direction
});
room.on("message", (message) => {
if (message.event === "player-state") {
applyRemotePlayerState(message.playerId, message.payload);
}
});
Important:
- Poplay provides room creation, joining, presence, and message transport.
- Your game still needs to implement gameplay synchronization.
- Your game decides player state, world state, host authority, disconnect handling, and match settlement.
- Keep realtime payloads small, ideally below 4KB.
7. Complete Config Example
{
"capabilities": {
"leaderboard": true,
"cloudSave": true,
"realtime": true
},
"leaderboards": [
{
"id": "global",
"name": "Global",
"sort": "desc",
"keepBest": true
}
],
"save": {
"slots": ["default"],
"maxBytes": 65536
},
"realtime": {
"maxPlayers": 2,
"visibility": "public",
"hostStrategy": "close-on-host-leave"
}
}
8. Submission Checklist
Before submitting:
index.htmlexists at the package root.- The SDK script is included.
Poplay.init()is called before platform APIs.poplay.config.jsonmatches the platform features used by the game.- Leaderboard, save, and realtime calls use
PoplayAPIs. - The game runs inside an iframe.
- Asset paths are relative.
- The game does not contain third-party platform branding or external game portal links.