Tournaments — prize-backed competitions on your game
- Written for
- + Written for
- Deprecated
- + Deprecated
- Applies to
- + Applies to
Tournaments — prize-backed competitions on your game
Run real, coin-prize score competitions on your own games. You create and manage them from your server (dev REST API / publisher SDK); players compete just by playing — scores auto-enroll into any live tournament, and the top finishers are paid out automatically when it ends. The coin prize pool is escrowed from your balance on create and refunded if you cancel.
From your server (publisher SDK / @portal/publisher-sdk)
import { ArcadeyClient } from "@portal/publisher-sdk";
const arc = new ArcadeyClient({ apiKey: process.env.ARCADEY_API_KEY! });
// Spin up a weekly tournament with a 5,000-coin pool split among the top 5.
const t = await arc.createTournament({
gameSlug: "my-game",
name: "Weekly Championship",
metric: "high_score", // or "total_score" (sums submissions)
prizePoolCoins: 5000, // escrowed from your balance now
maxWinners: 5, // 3:2:1-style descending split, coins conserved
endsAt: new Date(Date.now() + 7 * 864e5),
});
await arc.getTournament(t.id); // { tournament, standings: [{ rank, handle, score, prizeCoins }] }
await arc.listTournaments({ gameSlug: "my-game" });
await arc.cancelTournament(t.id); // refunds the prize pool if not yet settledThe same endpoints are a plain REST API (POST /v1/dev/tournaments, GET /v1/dev/tournaments, POST /v1/dev/tournaments/:id/cancel) authed with your arc_live_ key — call them from any language.
From inside the game (GameSDK.tournaments)
Show the competition and let players opt in. You don't wire up scoring — GameSDK.submitScore() already feeds every live tournament.
GameSDK.tournaments.getActive().then(function (t) {
if (!t) return;
// t = { id, name, prizePoolCoins, endsAt, entries, joined, myRank }
showBanner(t.name + " — 🪙 " + t.prizePoolCoins + " pool, you're #" + (t.myRank || "—"));
});
GameSDK.tournaments.list(); // all live/upcoming for this game
GameSDK.tournaments.join(tournamentId); // opt in (so you appear before scoring)
GameSDK.tournaments.getStandings(id).then(function (r) {
// r = { tournament, standings: [{ rank, handle, score, prizeCoins }] }
});
GameSDK.submitScore(myScore); // auto-counts toward any live tournamentSettlement is automatic: when the window closes, entries are ranked, the pool is paid out to the top maxWinners (rank 1 gets the biggest slice; coins are always conserved and any unawarded remainder is refunded to you), winners are notified, and the standings are frozen with each player's prize.