Achievements and stats
An achievement is a goal a player unlocks once, worth 10 points on their Velven profile when your space is listed and has a creator. A stat is a named counter per player, and an achievement with a trigger unlocks by itself when its stat gets there. You declare both; Velven keeps them, draws a toast for each unlock and lists them on your space's Velven page.
Declare achievements and stats
Declare them in the page's block, beside the boards. An unlock of a key you never declared answers no_achievement, and a stat you never declared answers no_stat.
<script type="application/velven+json">{"boards":[{"key":"main","trust":"client"}], "stats":[{"key":"kills","label":"Kills"}], "achievements":[ {"key":"first-blood","title":"First Blood","description":"Win a round"}, {"key":"centurion","title":"Centurion","description":"100 kills","trigger":{"stat":"kills","atLeast":100}}, {"key":"hidden-door","title":"Found it","secret":true,"icon":"icons/door.png"} ]}</script>Velven reads the block when the space is listed and on its background check every 6 hours; “Check my page now” on the edit page's Leaderboards tab reads it at once. There are 2 other places to declare them:
- A space hosted on Velven declares them in
velven.json, with the samestatsandachievementskeys: a version that names them syncs them when it goes live; a preview uses the live space's. Hosting has the file. - Without a deploy, send
{ "stats": [...], "achievements": [...] }withPUT /api/spaces/<slug>/achievementsand your API token. Only what you name is written, and the page's next sync overwrites a key it also names.GETon the same address answers what Velven holds.
Note: Remove an achievement or a stat from the block and it is withdrawn: hidden, with the players' unlocks and values kept. Name it again and it comes back.
Fields
An achievement takes these fields; only key and title are required:
key1 to 32 lowercase letters, digits,-or_- The id your calls use. Unique among the space's achievements.
title1 to 60 characters- The name the toast, the space's page and the player's profile show.
descriptionUp to 200 charactersDefault empty- What earns it.
secrettrueorfalseDefaultfalse- Hidden, title and all, until the player earns it.
listanswers it with a null title and description until then. iconUp to 500 characters- An https address, or a path read against your page's address: a file next to a linked page, or a file in a hosted upload. Anything else shows no icon.
trigger{ "stat": key, "atLeast": number }- Unlocks the achievement when the named stat reaches
atLeast. The stat must be declared in the same place.
A stat takes key (the same rule) and an optional label of up to 40 characters, for you to draw. Up to 50 achievements and 50 stats per space, withdrawn ones aside; declaring more answers too_many.
Unlock and count
Unlock when the player earns it, and write stats as they change. Each call needs a signed-in player.
const got = await Velven.achievements.unlock("first-blood");// { ok: true, achievement: "first-blood", title, unlocked, points: 10, total }, points 0 where it counts noneconst kills = await Velven.stats.add("kills", 1); // or stats.set("kills", 42)// { ok: true, stat: "kills", value: 43, unlocked: [ ... ] }, the triggers this value reachedconst now = await Velven.stats.get("kills"); // { ok: true, stat: "kills", value: 43 }, 0 before a first writeconst all = await Velven.achievements.list();// { ok: true, achievements: [{ key, title, description, icon, secret, trigger, points, unlocked, unlockedAt, holders, players, share }] }- An unlock is idempotent:
unlockedisfalsewhen the player already held it, so call it whenever the goal is met.totalis the player's points across Velven. - Points count on a listed space with a creator: its creator's own unlocks count none, and an achievement you stop declaring stops counting. Where an unlock counts none (your own, a page published without an account, the sandbox), it answers
points: 0and Velven's toast shows no points. stats.addtakes a negative number to take away. A value that is not a finite number, or a key that is not one, throws aTypeErrorbefore anything is sent.listanswers every achievement in the order you declared them, with the player's own unlocks.shareis the part of the space's players who hold it, from 0 to 1:holdersout ofplayers, where a player is anyone with an achievement or a stat in the space.
onAchievement hears every unlock the player earns, from unlock or from a stat reaching a trigger:
const stop = Velven.onAchievement((a) => console.log(`${a.title} +${a.points}`)); // { key, title, description, icon, points }The page and your server (with the space's secret) unlock the same achievements. An unlock from your server is marked trusted, and a page unlock your server repeats becomes trusted, so for a goal your server referees, such as beating a boss, unlock it there.
The unlock toast
Velven draws a toast over the corner of the frame for each unlock, such as “Achievement unlocked: First Blood, +10”, so you need draw nothing. If your space draws its own from onAchievement, turn Velven's off in one of 3 ways:
<script src="https://velven.ai/sdk/v1.js" data-toasts="false"></script>import { createVelven } from "@velven/sdk";const Velven = createVelven({ toasts: false });{ "toasts": false }velven.json is for a space hosted on Velven, where Velven adds the script tag for you.
On your space's Velven page
The space's Velven page has an Achievements section: every achievement with its icon, the share of players who hold it and, for a signed-in player, which ones they have. A secret achievement shows as hidden until the player earns it. An unlock that counts adds 10 points to the player's profile, where the total and their recent unlocks show; the section shows points only where they count.
Error codes
| Code | Meaning |
|---|---|
signed_out | No player is signed in. Offer signIn() from a button. |
no_achievement, no_stat | The space declares no such key, or it was withdrawn. |
invalid_value | The stat's value is not a finite number: an answer to your server, since the page's call throws first. |
unavailable | Not inside Velven, on a space not published with a verified owner, or on a Velven page too old to know achievements. |
banned, rate_limited, failed | As for scores. |
- Code
signed_out- Meaning
- No player is signed in. Offer
signIn()from a button.
- Code
no_achievement,no_stat- Meaning
- The space declares no such key, or it was withdrawn.
- Code
invalid_value- Meaning
- The stat's value is not a finite number: an answer to your server, since the page's call throws first.
- Code
unavailable- Meaning
- Not inside Velven, on a space not published with a verified owner, or on a Velven page too old to know achievements.
- Code
banned,rate_limited,failed- Meaning
- As for scores.
On localhost achievements and stats come from your block and live in memory: an unlock reaches onAchievement, and a stat reaching a trigger unlocks it. Local testing has the rest.